zoukankan      html  css  js  c++  java
  • Difference between Seek Predicate and Predicate

    Difference between Seek Predicate and Predicate

    Let's throw one million rows into a temp table along with a few columns:

    CREATE TABLE #174860 (
    PK INT NOT NULL, 
    COL1 INT NOT NULL,
    COL2 INT NOT NULL,
    PRIMARY KEY (PK)
    );
    
    INSERT INTO #174860 WITH (TABLOCK)
    SELECT RN
    , RN % 1000
    , RN % 10000
    FROM 
    (
        SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
        FROM   master..spt_values v1,
               master..spt_values v2
    ) t;
    
    CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);
    

    Here I have a clustered index (by default) on the PK column. There's a nonclustered index on COL1 that has a key column of COL1 and includes COL2.

    Consider the following query:

    SELECT *
    FROM #174860
    WHERE PK >= 15000 AND PK < 15005
    AND COL2 = 5000;
    

    Here I'm not using BETWEEN because Aaron Bertrand is hanging around this question.

    How should SQL Server optimizer that query? Well, I know that the filter on PK will reduce the result set to five rows. SQL server can use the clustered index to jump to those five rows instead of reading through all million rows in the table. However, the clustered index only has the PK column as a key column. Once the row is read into memory we need to apply the filter on COL2. Here, PK is a seek predicate and COL2 is a predicate.

    SQL server finds five rows using the seek predicate and further reduces those five rows to one row with the normal predicate.

    If I define the clustered index differently:

    CREATE TABLE #174860 (
    PK INT NOT NULL, 
    COL1 INT NOT NULL,
    COL2 INT NOT NULL,
    PRIMARY KEY (COL2, PK)
    );
    

    And run the same query I get different results:

    https://www.sqlservice.se/what-is-the-difference-between-a-predicate-and-a-seek-predicate/ 

    In this case, SQL Server can seek using both columns in the WHERE clause. Exactly one row is read from the table using the key columns.

    For one more example consider this query:

    SELECT *
    FROM #174860
    WHERE COL1 = 500
    AND COL2 = 3545;
    

    The IX_174860_IX index is a covering index because it contains all of the columns needed for the query. However, only COL1 is a key column. SQL Server can seek with that column to find the 1000 rows with a matching COL1 value. It can further filter down those rows on the COL2 column to reduce the final result set to 0 rows.

    https://www.sqlservice.se/what-is-the-difference-between-a-predicate-and-a-seek-predicate/

    If you look at the Index Seek operator in a query plan of a SQL Server SELECT query, you will sometimes see that you have both a Seek Predicate and also a Predicate.

    So what is the difference between these two properties of the Index seek?

    Seek Predicate is the seek operation that uses the b-tree part of the index to find matching rows.

    Predicate is an operation that after the Seek Predicate operation does additional filterin using non-key columns (and sometimes also on indexed columns). If this is a non clustered index it seems unintuitive to me that we would not use only Seek Predicate (except on included columns) but I have seen i happen, and my theory so far is that it might be related to statistics.

    In any case, you should expect much better performance from Seek Predicate operations only Index seeks compared to Index Seeks that include both Seek Predicate and Predicate properties.

  • 相关阅读:
    ZT:POI操作PPT
    ADO.NET 2.0 Dataset和Datatable 新功能新特性
    ADO.NET 2.0 大批量数据操作和多个动态的结果集
    浏览.NET Framework 2.0 类型库中新增的常用功能
    ASP.NET程序中常用代码汇总(四)
    保存div与页面滚动条的位置
    在ASP.NET中实现AJAX
    ASP.NET 2.0中隐藏listbox的某一项
    泛型最佳实践C#
    ASP.NET 2.0 验证控件新的功能
  • 原文地址:https://www.cnblogs.com/chucklu/p/14823407.html
Copyright © 2011-2022 走看看