Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么索引搜索在统计中显示高扫描计数?_Sql_Sql Server - Fatal编程技术网

Sql 为什么索引搜索在统计中显示高扫描计数?

Sql 为什么索引搜索在统计中显示高扫描计数?,sql,sql-server,Sql,Sql Server,在不深入太多细节的情况下,我有一个使用所有聚集和非聚集索引查找生成执行计划的查询(听起来很有希望)。不幸的是,查询的性能很差,我很难理解为什么 我正在使用设置统计io,可以看到其中一个表正在生成大量扫描和逻辑/物理读取: SET statistics io ON go SELECT order_number, audit_id, orderadmission_net_paid_delta / 100.00, 'Admi

在不深入太多细节的情况下,我有一个使用所有聚集和非聚集索引查找生成执行计划的查询(听起来很有希望)。不幸的是,查询的性能很差,我很难理解为什么

我正在使用
设置统计io,可以看到其中一个表正在生成大量扫描和逻辑/物理读取:

SET statistics io ON

go

    SELECT order_number,
           audit_id,
           orderadmission_net_paid_delta / 100.00,
           'Admission',
           orderadmission_net_paid_delta / 100.00,
           performance_gl_description1,
           section_data1,
           performance_gl_code,
           price_type_data1,
           year(performance_start_date),
           month(performance_start_date),
           paymentmethod_type,
           paymentmethod_name,
           ''
    FROM   JCRProdReplication.dbo.ts_audit WITH (NOLOCK)
           JOIN JCRProdReplication.dbo.ts_order_admission WITH (NOLOCK)
             ON orderadmission_audit_id = audit_id
           LEFT JOIN JCRProdReplication.dbo.ts_order WITH (NOLOCK)
             ON order_id = orderadmission_order_id
           LEFT JOIN JCRProdReplication.dbo.ts_performance WITH (NOLOCK)
             ON performance_id = orderadmission_performance_id
           LEFT JOIN JCRProdReplication.dbo.ts_seat WITH (NOLOCK)
             ON seat_id = orderadmission_seat_id
           LEFT JOIN JCRProdReplication.dbo.ts_section WITH (NOLOCK)
             ON section_id = seat_section_id
           LEFT JOIN JCRProdReplication.dbo.ts_price_type WITH (NOLOCK)
             ON price_type_id = orderadmission_price_type_id
           LEFT JOIN JCRProdReplication.dbo.ts_order_payment WITH (NOLOCK)
             ON orderpayment_audit_id = audit_id
           LEFT JOIN JCRProdReplication.dbo.ts_payment_method WITH (NOLOCK)
             ON paymentmethod_id = orderpayment_paymentmethod_id
    WHERE  audit_time >= '20140107'
           AND audit_time < '20140108' 

在理解为什么索引搜索会在统计数据中实际显示大量扫描/读取时,我的下一步是什么?(我在谷歌上搜索了一整天,没有找到任何解释)。

统计IO报告的扫描计数可能不是你所想的

范例

USE tempdb;
SET NOCOUNT ON;

CREATE TABLE Num1 (N INT PRIMARY KEY);

CREATE TABLE Num2 (N INT);
CREATE CLUSTERED INDEX IX ON Num2(N);

INSERT INTO Num1
OUTPUT      inserted.N
INTO Num2
SELECT number
FROM   master..spt_values
WHERE  type = 'P'
       AND number BETWEEN 1 AND 1000

SET STATISTICS IO ON;

SELECT *, sys.fn_PhysLocFormatter(N2.%%physloc%%)
FROM   Num1 N1
       INNER LOOP JOIN Num2 N2
         ON N1.N = N2.N

SET STATISTICS IO OFF;

DROP TABLE Num1, Num2
给出计划

和输出

Table 'Num2'. Scan count 1000, logical reads 2002
Table 'Num1'. Scan count 1, logical reads 3
尽管计划显示搜索,但仍报告了1000次扫描

由于索引未声明为唯一,因此每次搜索都是部分扫描。索引在数字中搜索1000次,然后每次搜索时都需要扫描索引,直到找到与数字不匹配的第一行

Num2.IX
索引有一个根页面和两个叶页面

2002年的逻辑读数细分如下

大多数搜索需要两次读取(单根页面和单叶页面)。其中两个seek(在我的例子中是数字622和623)在读取两个叶页时进行了三次逻辑读取

它们分别是第一页的最后一行和第二页的第一行

对于编号
622
,需要读取下一页的下一行,以查看该行是否重复。对于编号
623
,解释是索引的结构如下

根页面具有每个较低页面上可能包含的最低值。由于索引未声明为唯一的,因此需要检查上一页,以防页面边界上有多个匹配行

下面的博客文章对解释
STATISTICS IO
输出有一些额外的解释


您是否能够发布查询本身?仅从这一点很难得出结论……我希望对
的问题有一个普遍的回答,为什么索引搜索在统计数据中显示高扫描计数?
。然后,我可以满怀希望地查看它们,以及它们是否可以寻址。我不认为这个查询会有帮助,但还是添加了一些内容。
288490/71877=4.0136622
因此每个搜索平均阅读4页。这个指数有多少级?
Table 'Num2'. Scan count 1000, logical reads 2002
Table 'Num1'. Scan count 1, logical reads 3