Stu*_*ler 22 performance join sql-server
在阅读了慢 SQL 查询后,不确定如何优化,这让我想到了查询的总体性能。当然,我们需要第一个表的结果(当其他表被连接时)在连接之前尽可能小(这个问题的内部连接),以使我们的查询更快一点。
例如,应该这样:
SELECT *
FROM ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2
Run Code Online (Sandbox Code Playgroud)
比以下更好/更快:
SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val
Run Code Online (Sandbox Code Playgroud)
我的理论如下(这可能不是正确的实现,我试图从我读过的 SQL Server 2008 内部书籍(MSFT Press)中记住):
因此,如果在上面的语句 #1 中,表较小,则 SQL 引擎在形成笛卡尔积时要做的工作较少。然后,当您到达 where 语句时,您将拥有一个简化的结果集,可从中过滤内存。
我可能离目标太远了,这是不真实的。就像我说的,这是一个理论。
你的意见?
注意:我刚刚想到这个问题,还没有机会自己进行任何测试。
注2:标记为SQL Server的,因为我不知道任何关于MySQL等的实施,请随时接听/评论反正
gbn*_*gbn 18
查询的逻辑处理在MSDN 上(由 Microsoft SQL Server 团队编写,而不是第 3 方)
1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE or WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP
Run Code Online (Sandbox Code Playgroud)
派生表遵循此,然后外部查询再次执行等等
虽然这是合乎逻辑的:不是实际的。无论SQL Server实际上是怎么做的,这些语义很荣幸的信。“实际”由查询优化器 (QO) 确定,您避免使用您提到的中间 Cartesion 产品。
值得一提的是,SQL 是声明性的:您说的是“什么”而不是“如何”,就像在过程/命令式编程(Java、.net)中一样。因此,在许多情况下说“这在此之前发生”是错误的(例如假设短路或 L-to-R WHERE 顺序)
在上面的例子中,无论结构如何,QO 都会生成相同的计划,因为它是一个简单的查询。
但是,QO 是基于成本的,对于复杂的查询,可能需要 2 周时间才能生成理想的计划。所以它确实“足够好”,但实际上并非如此。
因此,您的第一个案例可能会帮助优化器找到更好的计划,因为 2 个查询的逻辑处理顺序不同。但它可能不是。
我在 SQL Server 2000 上使用了这个技巧,将报告查询的速度性能提高了 60 倍。随着 QO 不断改进版本,它会更好地解决这些问题。
还有你提到的那本书:对此有一些争议
请参见 SO 和后续链接:https : //stackoverflow.com/q/3270338/27535
SQL 查询本质上不是过程性的,连接运算符没有自上而下的处理。示例查询中表的排序对执行计划没有影响,因为它们在逻辑上是等效的,并且会生成完全相同的计划。
您已经评估了查询优化器在为此查询生成计划时可能考虑的两个选项。影响计划选择的主要因素是所涉及表格的统计数据以及与任何候选计划中的运营商选择相关的成本。
一个非常简单的两表连接(例如您的示例)可以满足数百种不同执行计划中的任何一种。优化器通过比较这些计划的成本来决定哪种是回答您的查询的最佳方式。
它有时会出错,您可以通过改进索引、更新统计数据和应用提示来帮助它做出更好的选择。在极少数情况下,您可能希望通过使用 FORCE ORDER 提示来强制执行顺序,但应谨慎使用。这是一把敲碎坚果的锤子,优化器通常可以通过提供更好的信息来制定更好的计划。