在Microsoft SQLServer Management Studio中执行查询时,如果选定工具栏中的 按钮,可以看到为查询生成的执行计划。执行计划以图形方式显示了SQL Server查询优化器选择的数据检索方法,如表扫描、排序、哈希匹配等。对于联接查询,SQL Server会根据联接表之
在Microsoft SQLServer Management Studio中执行查询时,如果选定工具栏中的按钮,可以看到为查询生成的执行计划。执行计划以图形方式显示了SQL Server查询优化器选择的数据检索方法,如表扫描、排序、哈希匹配等。对于联接查询,SQL Server会根据联接表之间的数据、索引等情况,选择使用嵌套循环联接、合并联接或哈希联接。
7.7.1嵌套循环联接
嵌套循环联接也称为“嵌套迭代”,它将一个联接输入用作外部输入表(显示为图形执行计划中的顶端输入),将另一个联接输入用作内部(底端)输入表。外部循环逐行处理外部输入表。内部循环会针对每个外部行执行,在内部输入表中搜索匹配行。简单地讲,就是扫描其中的一个联接表,并为该表中的每一行在另一个联接表中搜索匹配行。
如果外部输入较小(不到10行)而内部输入较大且预先创建了索引,则嵌套循环联接尤其有效。在许多小事务中(如那些只影响较小的一组行的事务),索引嵌套循环联接优于合并联接和哈希联接。但在大型查询中,嵌套循环联接通常不是最佳选择。
例如,下面的查询由于Sales.Customer表行数只有1行,而Sales.SalesOrderHeader数据量较大,因此将使用嵌套循环联接,生成的执行计划如图7-11所示。
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer
INNER JOINSales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID
WHERE Customer.CustomerID = 1;
图7-11使用嵌套循环的执行计划
在该计划中存在两个嵌套循环,其中只有左边的嵌套循环符用于Sales.Customer与Sales.SalesOrderHeader的联接,而右边的嵌套循环是用于Sales.SalesOrderHeader的索引查找与物理行定位(键查找)之间的联接。执行计划右上角的Sales.Customer表被作为外部输入,在聚集索引中查找客户。对于每个客户,嵌套循环运算将对SalesOrderHeader.CustomerID列上的IX_SalesOrderHeader_CustomerID索引执行一次查找,然后再跟一个键查找来定位要访问的数据行。
7.7.2合并联接
合并联接要求两个输入都在合并列上排序,合并列由联接谓词的等效(ON)子句定义。由于每个输入都已排序,因此合并联接将从每个输入获取一行并将其进行比较。例如,对于内联接操作,如果行相等则返回。如果行不相等,则废弃值较小的行并从该输入获得另一行。这一过程将重复进行,直到处理完所有的行为止。
合并联接操作可以是常规操作,也可以是多对多操作。多对多合并联接使用临时表存储行。如果每个输入中有重复值,则在处理其中一个输入中的每个重复项时,另一个输入必须重绕到重复项的开始位置。
合并联接本身的速度很快,但是如果合并列上未建立索引,选择合并联接有可能会非常费时,因为它首先要对列进行排序操作。然而,如果数据量很大且能够从索引中获得预排序的所需数据,则合并联接通常是最快的可用联接算法。
例如,下面的查询语句将获取订单的详细信息,由于SalesOrderHeader和SalesOrderDetail在合并列SalesOrderID上都具有聚集索引,已经将列进行了排序,所以查询优化器会选择合并联接。如图7-12所示。
USE AdventureWorks;
GO
SELECT *
FROM Sales.SalesOrderHeader
INNER JOINSales.SalesOrderDetail
ONSalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID;
图7-12使用合并联接的执行计划
7.7.3哈希联接
哈希联接可以有效处理未排序的大型非索引输入。因此,它对处理复杂查询的中间结果很有用。查询的中间结果是未经索引的,而且通常不会为查询计划中的下一个操作进行适当的排序。并且,查询优化器只估计中间结果的大小。而对于复杂查询,估计可能有很大的误差,因此如果中间结果比预期的大得多,则处理中间结果的算法不仅必须有效而且必须适度弱化。再像合并联接那样严格要求具备排序列,对于中间结果而言是不现实的,排序成本的付出可能要远远大于数据的直接检索成本。
选择哈希联接的两种情况:一是没有为联接创建合适的索引,二是中间结果比较大。
哈希联接有两种输入:生成输入和探测输入。查询优化器会选择二者中较小的那个作为生成输入,对联接列值应用哈希函数,将生成输入中的行分配到哈希桶中。哈希桶是一种存放所访问数据位置的结构,有了它,进行数据检索时,可以避免不必要的表扫描。
为了验证无索引情况下的哈希联接使用,首先使用下面的语句创建Sales.Customer和Sales.SalesOrderHeader表的副本。
USE AdventureWorks;
GO
SELECT TOP 10 *
INTO MyCustomer
FROM Sales.Customer
ORDER BY CustomerID;
SELECT TOP 100 *
INTO MySalesOrderHeader
FROM Sales.SalesOrderHeader
ORDER BY CustomerID;
执行下面的查询,可以看到如图7-13所示的执行计划。
SELECT *
FROM MyCustomer
INNER JOINMySalesOrderHeader
ONMyCustomer.CustomerID = MySalesOrderHeader.CustomerID;
图7-13使用哈希联接的执行计划
下面再来看一个比较有趣的示例。下面的查询语句中仅选择了Sales.Customer中CustomerID = 1的行与Sales.SalesOrderHeader进行联接,由于联接行数很小,所产生中间结果的数据量也比较小,因此,可以看到查询优化器为语句使用了嵌套循环联接。如图7-14所示。
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer
INNER JOINSales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID
WHERE Customer.CustomerID = 1;
图7-14数据量较小时使用嵌套循环联接
同样是上面的联接,去除掉WHERE筛选条件后数据量明显增大,执行该语句会发现查询优化器使用了哈希联接方式。如图7-15所示。
SELECT *
FROM Sales.Customer
INNER JOINSales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID;
图7-15数据量较大时使用哈希联接
7.7.4使用联接提示强制联接策略
联接提示用于指定查询优化器在两个表之间强制执行联接策略,提示符包括LOOP JOIN、MERGE JOIN和HASH JOIN,分别用于嵌套循环、哈希和合并联接。如果指定了多个联接提示,则优化器从允许的联接策略中选择开销最少的联接策略。此外,也可以使用OPTION子句指定联接策略。但是这种方式会影响查询中的所有联接,通常用于旧式联接语法。
1.为每个联接指定单独的联接策略
可以在FROM子句中使用LOOP JOIN、MERGE JOIN和HASH JOIN提示符为每个联接单独指定联接策略。例如,下面的查询语句指定使用嵌套循环联接。
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer
INNER LOOPJOIN Sales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID;
又如,下面的查询语句指定使用合并联接。
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer
INNERMERGE JOIN Sales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID;
在多表联接中使用联接提示时,会影响联接的执行顺序。在前面介绍了,在不影响返回结果正确的情况下,查询优化器会按照效率优先的原则,选择首先执行的联接。例如,下面语句的执行计划如图7-16所示,可以看到首先执行的是Sales.SalesOrderHeader与Sales.SalesOrderDetail的联接,然后将联接结果再与Sales.Customer进行联接。
USE AdventureWorks;
GO
SELECT *
FROM Sales.Customer
INNER JOINSales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID
INNER JOINSales.SalesOrderDetail
ONSalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID;
图7-16未使用联接提示的执行计划
下面的语句为Sales.Customer和Sales.SalesOrderHeader指定了合并联接提示,并且这个提示仅对这两个表起作用,与Sales.SalesOrderDetail的联接策略仍旧由查询优化器决定。由于明确指定了Sales.Customer与Sales.SalesOrderHeader使用合并联接,优化器会先执行该联接,而不是先执行Sales.SalesOrderHeader与Sales.SalesOrderDetail的联接。否则,就会造成Sales.Customer与Sales.SalesOrderHeader和Sales.SalesOrderDetail的联接结果再执行合并联接。图7-17是该语句的执行计划。
SELECT *
FROM Sales.Customer
INNERMERGE JOIN Sales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID
INNER JOINSales.SalesOrderDetail
ONSalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID;
图7-17使用联接提示后的执行计划
如果希望Sales.Customer与Sales.SalesOrderHeader和Sales.SalesOrderDetail的联接结果执行合并联接,则应当使用嵌套联接的方式实现,参考下面的语句:
SELECT *
FROM Sales.Customer
INNERMERGE JOIN (Sales.SalesOrderHeader
INNER JOIN Sales.SalesOrderDetail
ONSalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID)
ONCustomer.CustomerID = SalesOrderHeader.CustomerID;
2.为全部联接指定统一的联接策略
当使用旧式联接语法时,应当使用OPTION子句指定联接策略,但是,这种策略会影响语句中的全部联接,无法为每个联接单独指定不同的联接策略,如:
SELECT *
FROM Sales.Customer, Sales.SalesOrderHeader,Sales.SalesOrderDetail
WHERE Customer.CustomerID =SalesOrderHeader.CustomerID
ANDSalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
OPTION (MERGE JOIN);
该语句的执行计划如图7-18所示,可以看到三个表之间全部使用了合并联接策略。
图7-18为全部联接使用统一联接策略的执行计划
在ANSI SQL:1992规范中,也可以使用OPTION子句,它同样也是影响语句中的全部联接,如:
SELECT *
FROM Sales.Customer
INNER JOINSales.SalesOrderHeader
ONCustomer.CustomerID = SalesOrderHeader.CustomerID
INNER JOINSales.SalesOrderDetail
ONSalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID
OPTION (MERGE JOIN);

存储过程是MySQL中的预编译SQL语句集合,用于提高性能和简化复杂操作。1.提高性能:首次编译后,后续调用无需重新编译。2.提高安全性:通过权限控制限制数据表访问。3.简化复杂操作:将多条SQL语句组合,简化应用层逻辑。

MySQL查询缓存的工作原理是通过存储SELECT查询的结果,当相同查询再次执行时,直接返回缓存结果。1)查询缓存提高数据库读取性能,通过哈希值查找缓存结果。2)配置简单,在MySQL配置文件中设置query_cache_type和query_cache_size。3)使用SQL_NO_CACHE关键字可以禁用特定查询的缓存。4)在高频更新环境中,查询缓存可能导致性能瓶颈,需通过监控和调整参数优化使用。

MySQL被广泛应用于各种项目中的原因包括:1.高性能与可扩展性,支持多种存储引擎;2.易于使用和维护,配置简单且工具丰富;3.丰富的生态系统,吸引大量社区和第三方工具支持;4.跨平台支持,适用于多种操作系统。

MySQL数据库升级的步骤包括:1.备份数据库,2.停止当前MySQL服务,3.安装新版本MySQL,4.启动新版本MySQL服务,5.恢复数据库。升级过程需注意兼容性问题,并可使用高级工具如PerconaToolkit进行测试和优化。

MySQL备份策略包括逻辑备份、物理备份、增量备份、基于复制的备份和云备份。1.逻辑备份使用mysqldump导出数据库结构和数据,适合小型数据库和版本迁移。2.物理备份通过复制数据文件,速度快且全面,但需数据库一致性。3.增量备份利用二进制日志记录变化,适用于大型数据库。4.基于复制的备份通过从服务器备份,减少对生产系统的影响。5.云备份如AmazonRDS提供自动化解决方案,但成本和控制需考虑。选择策略时应考虑数据库大小、停机容忍度、恢复时间和恢复点目标。

MySQLclusteringenhancesdatabaserobustnessandscalabilitybydistributingdataacrossmultiplenodes.ItusestheNDBenginefordatareplicationandfaulttolerance,ensuringhighavailability.Setupinvolvesconfiguringmanagement,data,andSQLnodes,withcarefulmonitoringandpe

在MySQL中优化数据库模式设计可通过以下步骤提升性能:1.索引优化:在常用查询列上创建索引,平衡查询和插入更新的开销。2.表结构优化:通过规范化或反规范化减少数据冗余,提高访问效率。3.数据类型选择:使用合适的数据类型,如INT替代VARCHAR,减少存储空间。4.分区和分表:对于大数据量,使用分区和分表分散数据,提升查询和维护效率。

tooptimizemysqlperformance,lofterTheSeSteps:1)inasemproperIndexingTospeedUpqueries,2)使用ExplaintplaintoAnalyzeandoptimizequeryPerformance,3)ActiveServerConfigurationStersLikeTlikeTlikeTlikeIkeLikeIkeIkeLikeIkeLikeIkeLikeIkeLikeNodb_buffer_pool_sizizeandmax_connections,4)


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

禅工作室 13.0.1
功能强大的PHP集成开发环境