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
如何在不访问showplan的情况下优化SQL查询?_Sql_Sql Server_Tsql_Query Optimization - Fatal编程技术网

如何在不访问showplan的情况下优化SQL查询?

如何在不访问showplan的情况下优化SQL查询?,sql,sql-server,tsql,query-optimization,Sql,Sql Server,Tsql,Query Optimization,我正在编写复杂的即席查询,以从客户端的SQL Server提取数据。有些查询需要半小时或更长时间才能运行,我需要它们在5分钟或更短时间内执行。不幸的是,我没有权限查看showplan或任何sys.dm视图来帮助我优化它们 我确实可以访问所有的信息\u模式和sys目录视图,因此我知道存在哪些索引,并且我还可以使用统计时间和IO来帮助我衡量更改的有效性 既然我没有比较展示计划的能力,我如何才能最好地使用这些工具来引导我的直觉,以尽量减少耗时的尝试和错误?或者是否有人有任何创新的解决方案,在过去为他们

我正在编写复杂的即席查询,以从客户端的SQL Server提取数据。有些查询需要半小时或更长时间才能运行,我需要它们在5分钟或更短时间内执行。不幸的是,我没有权限查看showplan或任何
sys.dm
视图来帮助我优化它们

我确实可以访问所有的
信息\u模式
sys
目录视图,因此我知道存在哪些索引,并且我还可以使用
统计时间
IO
来帮助我衡量更改的有效性

既然我没有比较展示计划的能力,我如何才能最好地使用这些工具来引导我的直觉,以尽量减少耗时的尝试和错误?或者是否有人有任何创新的解决方案,在过去为他们工作过


编辑:我只有db_DataReader权限——我不能创建新对象或索引,但我可以创建临时表并为它们编制索引

以下是我将探讨的策略。根据经验法则,绝大多数查询优化都是通过使用覆盖索引来避免表扫描和哈希匹配联接来实现的

查看需要包含在查询中的每个表,以及需要在
JOIN ON
子句或
WHERE
子句中使用的列。如果表有一个包含所有这些列的索引,那么您可以继续在查询中使用该表。您甚至可以使用查询提示来强制查询使用覆盖索引,但不需要它

如果表中没有这样的索引,那么您需要用使用现有索引可以获得的最小数据量填充临时表

举一个超级简单的例子,假设有一个包含10列和100万行的表,它在
Column1
上只有一个索引。在查询中,您需要
加入
列2
上的表,并在结果集中包含
列3
(仅限)

但除此之外,对于最终的结果集,您只对
Column1
值在1-100之间的数据感兴趣

我将创建一个只有
列2
列3
的临时表,在
列2
上有一个聚集索引,并用
插入填充它。选择
,使用
列1
上的
WHERE
子句过滤器从原始表获取数据,以仅获取我需要的行


通过这种方式,您可以在尽可能最小的表上建立索引,这有望使您在使用扫描原始表的查询时获得显著的性能提升。

研究SQL Server的内部结构并实践查询计划预测的艺术

通过对已知数据(基数、密度、分布等)编写查询来练习。确保查询足够复杂,这是一个挑战。然后看看你是否能在脑海中描绘出这个计划。这和实际情况相比吗。当您开始计算SQL何时会选择循环v散列v合并联接类型和其他类似的操作(如排序、top等)时。。。然后你开始对它有感觉了

关于内部文档,从来没有一本书比这本更好。因为Ken已经不在了:(,我不确定现在最好的书是什么。我通过感觉学习如何做到这一点的方法是研究内部

您可以下载免费版本的SQL Server(许多版本),以便查看查询计划:。请将其用于实践

实践中有许多记录良好的样本数据库:

在使用图形查询计划之前,我们使用时间、io统计数据和showplan


实用的方法是:不要在客户端生产数据库中运行复杂的查询,而是从中提取必要的数据。然后将其余的查询运行到您自己的实例或测试环境。

您是否需要访问
sys.dm uu视图
才能访问SSMS中的
执行计划
?如果是客户端的SQL Server,则需要您是否有权在其上创建索引?它们在SQL Server中是独立的安全文件。我曾希望使用sys.dm_uu视图可以让我查看计划缓存或当前执行查询的计划。当然,您的客户端可以授予您访问权限或运行查询并为您获取执行计划的副本。老实说,如果您没有允许建立索引,我不知道看到执行计划会有多大帮助。请看下面我的答案,如果这不起作用,也许会坚持得到执行计划。OP知道这些。问题是,“我如何最好地使用这些工具来引导我的直觉,以尽量减少耗时的尝试和错误?”因此,他们可能在寻求某种方法。Op明确提到,他不能使用
showplan
查询提示来添加您的答案。这就是他们在解决实际问题时所应考虑的问题。
    SET STATISTICS IO ON
SET STATISTICS TIME ON
go
SET SHOWPLAN_ALL ON
go

SELECT o.*, od.*
    FROM [dbo].[Orders] o
        INNER JOIN [dbo].[Order Details] od
            ON o.OrderID = od.OrderID
    WHERE od.OrderID = 10248
go


    SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
StmtText                  StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument DefinedValues EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList Warnings Type                                                             Parallel EstimateExecutions
------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ -------- ------------- ------------- ------------- ------------- ----------- ---------------- ---------- -------- ---------------------------------------------------------------- -------- ------------------
SET STATISTICS IO ON      1           1           0           NULL                           NULL                           1        NULL          NULL          NULL          NULL          NULL        NULL             NULL       NULL     SET STATS                                                        0        NULL
SET STATISTICS TIME ON    2           2           0           NULL                           NULL                           2        NULL          NULL          NULL          NULL          NULL        NULL             NULL       NULL     SET STATS                                                        0        NULL

(2 row(s) affected)

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
StmtText               StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument DefinedValues EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList Warnings Type                                                             Parallel EstimateExecutions
---------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ -------- ------------- ------------- ------------- ------------- ----------- ---------------- ---------- -------- ---------------------------------------------------------------- -------- ------------------
SET SHOWPLAN_ALL ON    1           1           0           NULL                           NULL                           1        NULL          NULL          NULL          NULL          NULL        NULL             NULL       NULL     SET ON/OFF                                                       0        NULL

(1 row(s) affected)

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
StmtText                                                                                                                                              StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument                                                                                                              DefinedValues                                                                                                                                                                                                                                          EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList                                                                                                                                                                                                                                                       Warnings Type                                                             Parallel EstimateExecutions
----------------------------------------------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ --------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------- ------------- ------------- ----------- ---------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------

SELECT o.*, od.*
    FROM [dbo].[Orders] o
        INNER JOIN [dbo].[Order Details] od
            ON o.OrderID = od.OrderID
    WHERE od.OrderID = 10248            1           1           0           NULL                           NULL                           1                                                                                                                     NULL                                                                                                                                                                                                                                                   3             NULL          NULL          NULL        0.00658094       NULL                                                                                                                                                                                                                                                             NULL     SELECT                                                           0        NULL
  |--Nested Loops(Inner Join)                                                                                                                         1           2           1           Nested Loops                   Inner Join                     NULL                                                                                                                  NULL                                                                                                                                                                                                                                                   3             0             1.254E-05     254         0.00658094       [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o].[RequiredDate], [o].[ShippedDate], [o].[ShipVia], [o].[Freight], [o].[ShipName], [o].[ShipAddress], [o].[ShipCity], [o].[ShipRegion], [o].[ShipPostalCode], [o].[ShipCountry], [od].[Ord NULL     PLAN_ROW                                                         0        1
       |--Clustered Index Seek(OBJECT:([Northwind].[dbo].[Orders].[PK_Orders] AS [o]), SEEK:([o].[OrderID]=(10248)) ORDERED FORWARD)                  1           3           2           Clustered Index Seek           Clustered Index Seek           OBJECT:([Northwind].[dbo].[Orders].[PK_Orders] AS [o]), SEEK:([o].[OrderID]=(10248)) ORDERED FORWARD                  [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o].[RequiredDate], [o].[ShippedDate], [o].[ShipVia], [o].[Freight], [o].[ShipName], [o].[ShipAddress], [o].[ShipCity], [o].[ShipRegion], [o].[ShipPostalCode], [o].[ShipCountry]  1             0.003125      0.0001581     231         0.0032831        [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o].[RequiredDate], [o].[ShippedDate], [o].[ShipVia], [o].[Freight], [o].[ShipName], [o].[ShipAddress], [o].[ShipCity], [o].[ShipRegion], [o].[ShipPostalCode], [o].[ShipCountry]            NULL     PLAN_ROW                                                         0        1
       |--Clustered Index Seek(OBJECT:([Northwind].[dbo].[Order Details].[PK_Order_Details] AS [od]), SEEK:([od].[OrderID]=(10248)) ORDERED FORWARD)  1           4           2           Clustered Index Seek           Clustered Index Seek           OBJECT:([Northwind].[dbo].[Order Details].[PK_Order_Details] AS [od]), SEEK:([od].[OrderID]=(10248)) ORDERED FORWARD  [od].[OrderID], [od].[ProductID], [od].[UnitPrice], [od].[Quantity], [od].[Discount]                                                                                                                                                                   3             0.003125      0.0001603     29          0.0032853        [od].[OrderID], [od].[ProductID], [od].[UnitPrice], [od].[Quantity], [od].[Discount]                                                                                                                                                                             NULL     PLAN_ROW                                                         0        1

(4 row(s) affected)