搜尋
首頁資料庫mysql教程调整SQLSERVER非最优执行计划

我们发出的 SQL 语句,如果没有对应的缓存,优化器都会创建一个相应的 执行 计划 。但是,优化器基于成本的优化过程,在面对比较复杂的 SQL 语句时,不会考虑所有的情况。因此有些时候,就会给出一个近似高效的 执行 计划 。同时,受生产环境负载的影响,可

    我们发出的SQL语句,如果没有对应的缓存,优化器都会创建一个相应的执行计划。但是,优化器基于成本的优化过程,在面对比较复杂的SQL语句时,不会考虑所有的情况。因此有些时候,就会给出一个近似高效的执行计划。同时,受生产环境负载的影响,可能优化的过程会更不彻底,因此我们就应该控制语句的复杂程度,以减少优化器考虑各种组合的可能性。

当系统的性能出现问题时,即便你的索引建的很完美,但有的时候因为选择度的问题,你还要考虑怎么样在选择度不高的时候避免对表的扫描。防止像在高速公路塞车一样,所有的查询都要等待再等待,就像公交车一样。虽然SQL2005中有INCLUDE的功能,打破了在建立非聚集索引时16个字段900个字节的限制。但包含过多的INCLUE字段的代价是浪费太多的磁盘空间。当然,我们可能不在乎磁盘空间开销,毕竟是客户买单。面对如此大的索引数据量,SQL2005也增加了备份的策略。用文件或文件组的方式来处理。但多文件或文件组的备份是基于多个备份基准的,因此给管理带来了一定的挑战性。所以,我们应该首先考虑好用既有的索引来优化查询。实在没有办法时才去考虑新建索引或调整索引的字段。没有最好的,只有追求一个更合适的索引,尽量减少创建太多的索引。因为这会给数据的修改造成负担。

在进行语句级的调优时,我们首先要明确一下调优的目的是什么。在有了合适的索引时,就是如何有效的利用它们在CPU、内存、I/O之间达到一个平衡。如果你的内存一直很紧张,我们就想办法避免那些占用太多内存的运算符的使用。每个运算符在特定的场合使用是很高效的,没有什么是一成不变的。只有我们多试,才能找到一个最佳的平衡点。

下面我们通过一个示例来演示一下对一个SQLSERVER生成的不是很高效的执行计划调整方法。调整前后的成本开销为9:1,这样就能提高系统的并发操作。

调整SQLSERVER非最优执行计划 

调整SQLSERVER非最优执行计划调整SQLSERVER非最优执行计划Code
调整SQLSERVER非最优执行计划SELECT P.Name,P.Color,PSC.Name AS SubcategoryName,PC.Name AS CategoryName,
调整SQLSERVER非最优执行计划    S.SalesOrderID,S.OrderDate,OD.LineTotal
调整SQLSERVER非最优执行计划    
FROM Production.Product P
调整SQLSERVER非最优执行计划    
JOIN Production.ProductSubcategory PSC
调整SQLSERVER非最优执行计划        
ON P.ProductSubcategoryID = PSC.ProductSubcategoryID
调整SQLSERVER非最优执行计划    
JOIN Production.ProductCategory PC
调整SQLSERVER非最优执行计划        
ON PSC.ProductCategoryID = PC.ProductCategoryID
调整SQLSERVER非最优执行计划    
JOIN Sales.SalesOrderDetail OD
调整SQLSERVER非最优执行计划        
ON OD.ProductID = P.ProductID
调整SQLSERVER非最优执行计划    
JOIN Sales.SalesOrderHeader S
调整SQLSERVER非最优执行计划        
ON OD.SalesOrderID = S.SalesOrderID
调整SQLSERVER非最优执行计划
WHERE S.SalesPersonID = 275 AND PSC.Name = N'Road Bikes'

 这个查询要查出某个销售人员的某个子类产品的销售情况及相关的产品的信息。我们知道该销售人员的所有销售产品中只有一部分会属于某一类的产品。因此,最终要查询的结果是下面两者的交集部分。随着两者交集部分的变化,SQLSERVER给出的总体的查询思路没有多大变化,因此我们应该进行干涉了。

调整SQLSERVER非最优执行计划 

下面是SQLSERVER为我们生成的执行计划

调整SQLSERVER非最优执行计划

部分图形计划显示如下:

调整SQLSERVER非最优执行计划

大家看到计划中对Sales.SalesOrderHeader表进行了一次扫描,而这张表是一个增长很快的表,所以对这样的表进行扫描是一种很耗时的查询。扫描是因为查询中有OrderDate,而这个字段没有索引。所以只有在聚集索引的叶级,也就是真正的数据页上才能获得此信息。同时,Sales.SalesOrderDetail中对应了很多订单明细项,这也是增长很快的表。这里的聚集索引查找是因为要查询LineTotal,这是个计算字段,上面同样也没建立索引。为了计算这个值,会消耗很多的CPU资源。

    我们知道查询中联接产品和订单的表是Sales.SalesOrderDetail,如果我们能通过唯有的两个查询条件先在索引级别中把两者的交集取出来,最终再去查询只在数据页级存在的数据就会减少很多的资源浪费。下面是调整后的查询过程:

  1. 用于保存销售人员销售的产品和该类产品的交集部分的表变量,此处使用表变量可以防止在过程中引起重新编译。http://www.cnblogs.com/tom-fu/archive/2008/03/09/1096993.html

    调整SQLSERVER非最优执行计划调整SQLSERVER非最优执行计划Code
    DECLARE @udt_sales TABLE
    (
        SalesOrderID          
    INT NOT NULL,
        SalesOrderDetailID    
    INT NOT NULL
    )

  2. 用于保存某类产品相关信息的表变量

    调整SQLSERVER非最优执行计划调整SQLSERVER非最优执行计划Code
    DECLARE @udt_products TABLE
    (
        ProductID            
    INT    NOT NULL,
        
    [Name]              [Name] NOT NULL,
        Color               
    nvarchar(15NULL,
        SubcategoryName    
    [Name] NOT NULL
        CategoryName        
    [Name] NOT NULL
    )    

  3. 因为Sales.SalesOrderHeader在SalesPersonID字段有非聚集索引,所以查询275的订单可直接在此索引中查找。同时,我们看到在Sales.SalesOrderDetail表的ProductID字段建了一个非聚集索引,而SalesOrderID,SalesOrderDetailID作为聚集索引是该索引的键值字段。所以只在这个非聚集索引中即可查询到SalesOrderIDSalesOrderDetailID,从而减少I/O的操作。执行过程如下图所示

    调整SQLSERVER非最优执行计划调整SQLSERVER非最优执行计划Code
    INSERT INTO @udt_sales
    SELECT OD.SalesOrderID,OD.SalesOrderDetailID 
    FROM Sales.SalesOrderHeader S
        
    JOIN Sales.SalesOrderDetail OD 
            
    ON OD.SalesOrderID = S.SalesOrderID AND S.SalesPersonID = 275 
        
    JOIN (Production.ProductSubcategory PSC
                
    JOIN Production.Product P    
                    
    ON P.ProductSubcategoryID = PSC.ProductSubcategoryID AND PSC.Name = N'Road Bikes')
           
    ON P.ProductID=OD.ProductID

调整SQLSERVER非最优执行计划

  1. 把产品相关的信息存于表变量中以避免在联接中多次查询这些表

    调整SQLSERVER非最优执行计划调整SQLSERVER非最优执行计划Code
    调整SQLSERVER非最优执行计划INSERT INTO @udt_products
    调整SQLSERVER非最优执行计划
    SELECT P.ProductID,P.Name,P.Color,PSC.Name,PC.Name
    调整SQLSERVER非最优执行计划
    FROM Production.Product P    
    调整SQLSERVER非最优执行计划        
    JOIN Production.ProductSubcategory PSC
    调整SQLSERVER非最优执行计划            
    ON P.ProductSubcategoryID = PSC.ProductSubcategoryID
    调整SQLSERVER非最优执行计划        
    JOIN Production.ProductCategory PC
    调整SQLSERVER非最优执行计划            
    ON PSC.ProductCategoryID = PC.ProductCategoryID
    调整SQLSERVER非最优执行计划
    WHERE PSC.Name = N'Road Bikes'

  2. 最终用取得的交集部分和订单及明细表联接,查询出S.OrderDate,OD.LineTotal。因为这时是用取得的较小的交集部分来查询,所以避免了对Sales.SalesOrderHeader的表扫描。

    调整SQLSERVER非最优执行计划调整SQLSERVER非最优执行计划Code
    调整SQLSERVER非最优执行计划SELECT UP.Name,UP.Color,UP.SubcategoryName,UP.CategoryName,
    调整SQLSERVER非最优执行计划        S.SalesOrderID,S.OrderDate,OD.LineTotal
    调整SQLSERVER非最优执行计划
    FROM @udt_sales US
    调整SQLSERVER非最优执行计划        
    INNER JOIN Sales.SalesOrderHeader S
    调整SQLSERVER非最优执行计划            
    ON US.SalesOrderID=S.SalesOrderID
    调整SQLSERVER非最优执行计划        
    JOIN Sales.SalesOrderDetail OD 
    调整SQLSERVER非最优执行计划            
    ON US.SalesOrderID=OD.SalesOrderID AND US.SalesOrderDetailID=OD.SalesOrderDetailID
    调整SQLSERVER非最优执行计划        
    JOIN @udt_products UP
    调整SQLSERVER非最优执行计划            
    ON OD.ProductID=UP.ProductID

     成本的开销大,不一定代表执行时间就慢。如果你在机器上执行,因为受语句执行时机器的资源使用情况,所以不能只单纯依靠执行时间来判断,如果你追求更快的速度可以想办法把它改成并行的方式,这时就会降低系统的并发性。当然如果在不影响并发性的情况下,SQLSERVER也会主动的选择使用并发的方式。把优化前后的语句分别一前一后的去执行,你会得到不同的执行时间。所以最终还是要看I/O和里面所包含的各个运算符的操作。同时,如果你的查询能占用更少的资源,则能提高系统的并发性。这样在总体上来讲,你的系统性能还是会提高一些。

    当然,如果再结合一些提示的使用可能还有更高效的查询方法,或是再调整一下执行的逻辑。同时,我所举的示例只是在查询条件的选择度不高时的情况,如果查询条件选择度很高的话,SQLSERVER执行的整个过程也不会和现在的这个样。INSERT INTO本身也是个耗能大户,如果相比有太多的数据时就不太合适了。大家可以自己试一下。丢车保帅,不同的查询条件两者的开销也会发生变化。我们唯有做好最坏的打算,防止因为选择度的变化造成的这种性能开销。基本的原则就是避免对增长很快的大表扫描,分解复杂的查询以减少优化器优化时考虑各种组合的可能性。因为它并不清楚你查询的逻辑到底是怎么样的。最终的执行结果如下。

调整SQLSERVER非最优执行计划

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
說明InnoDB重做日誌和撤消日誌的作用。說明InnoDB重做日誌和撤消日誌的作用。Apr 15, 2025 am 12:16 AM

InnoDB使用redologs和undologs確保數據一致性和可靠性。 1.redologs記錄數據頁修改,確保崩潰恢復和事務持久性。 2.undologs記錄數據原始值,支持事務回滾和MVCC。

在解釋輸出(類型,鍵,行,額外)中要查找的關鍵指標是什麼?在解釋輸出(類型,鍵,行,額外)中要查找的關鍵指標是什麼?Apr 15, 2025 am 12:15 AM

EXPLAIN命令的關鍵指標包括type、key、rows和Extra。 1)type反映查詢的訪問類型,值越高效率越高,如const優於ALL。 2)key顯示使用的索引,NULL表示無索引。 3)rows預估掃描行數,影響查詢性能。 4)Extra提供額外信息,如Usingfilesort提示需要優化。

在解釋中使用臨時狀態以及如何避免它是什麼?在解釋中使用臨時狀態以及如何避免它是什麼?Apr 15, 2025 am 12:14 AM

Usingtemporary在MySQL查詢中表示需要創建臨時表,常見於使用DISTINCT、GROUPBY或非索引列的ORDERBY。可以通過優化索引和重寫查詢避免其出現,提升查詢性能。具體來說,Usingtemporary出現在EXPLAIN輸出中時,意味著MySQL需要創建臨時表來處理查詢。這通常發生在以下情況:1)使用DISTINCT或GROUPBY時進行去重或分組;2)ORDERBY包含非索引列時進行排序;3)使用複雜的子查詢或聯接操作。優化方法包括:1)為ORDERBY和GROUPB

描述不同的SQL交易隔離級別(讀取未讀取,讀取,可重複的讀取,可序列化)及其在MySQL/InnoDB中的含義。描述不同的SQL交易隔離級別(讀取未讀取,讀取,可重複的讀取,可序列化)及其在MySQL/InnoDB中的含義。Apr 15, 2025 am 12:11 AM

MySQL/InnoDB支持四種事務隔離級別:ReadUncommitted、ReadCommitted、RepeatableRead和Serializable。 1.ReadUncommitted允許讀取未提交數據,可能導致臟讀。 2.ReadCommitted避免臟讀,但可能發生不可重複讀。 3.RepeatableRead是默認級別,避免臟讀和不可重複讀,但可能發生幻讀。 4.Serializable避免所有並發問題,但降低並發性。選擇合適的隔離級別需平衡數據一致性和性能需求。

MySQL與其他數據庫:比較選項MySQL與其他數據庫:比較選項Apr 15, 2025 am 12:08 AM

MySQL適合Web應用和內容管理系統,因其開源、高性能和易用性而受歡迎。 1)與PostgreSQL相比,MySQL在簡單查詢和高並發讀操作上表現更好。 2)相較Oracle,MySQL因開源和低成本更受中小企業青睞。 3)對比MicrosoftSQLServer,MySQL更適合跨平台應用。 4)與MongoDB不同,MySQL更適用於結構化數據和事務處理。

MySQL索引基數如何影響查詢性能?MySQL索引基數如何影響查詢性能?Apr 14, 2025 am 12:18 AM

MySQL索引基数对查询性能有显著影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

MySQL:新用戶的資源和教程MySQL:新用戶的資源和教程Apr 14, 2025 am 12:16 AM

MySQL學習路徑包括基礎知識、核心概念、使用示例和優化技巧。 1)了解表、行、列、SQL查詢等基礎概念。 2)學習MySQL的定義、工作原理和優勢。 3)掌握基本CRUD操作和高級用法,如索引和存儲過程。 4)熟悉常見錯誤調試和性能優化建議,如合理使用索引和優化查詢。通過這些步驟,你將全面掌握MySQL的使用和優化。

現實世界Mysql:示例和用例現實世界Mysql:示例和用例Apr 14, 2025 am 12:15 AM

MySQL在現實世界的應用包括基礎數據庫設計和復雜查詢優化。 1)基本用法:用於存儲和管理用戶數據,如插入、查詢、更新和刪除用戶信息。 2)高級用法:處理複雜業務邏輯,如電子商務平台的訂單和庫存管理。 3)性能優化:通過合理使用索引、分區表和查詢緩存來提升性能。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。