如何編寫更好的SQL查詢:終極指南-第二部分

来源:http://www.cnblogs.com/powertoolsteam/archive/2017/09/05/write-better-sql-queries-definitive-guide-part-2.html
-Advertisement-
Play Games

結構化查詢語言(SQL)是數據挖掘分析行業不可或缺的一項技能。對於SQL來說,編寫查詢語句只是第一步,確保查詢語句高效並且適合於你的資料庫操作工作,才是最重要的。 ...


上一篇文章中,我們學習了 SQL 查詢是如何執行的以及在編寫 SQL 查詢語句時需要註意的地方。

下麵,我進一步學習查詢方法以及查詢優化。

 

基於集合和程式的方法進行查詢

反向模型中隱含的事實是,建立查詢時基於集合和程式的方法之間存在著不同。

  • 查詢的程式方法是一種非常類似於編程的方法:你告訴系統需要做些什麼以及如何做。例如上一篇文章中的示例,通過執行一個函數然後調用另一個函數來查詢資料庫,或者使用包含迴圈、條件和用戶定義函數(UDF)的邏輯方式來獲得最終查詢結果。你會發現通過這種方式,一直在請求一層一層中數據的子集。這種方法也經常被稱為逐步或逐行查詢。
  • 另一種是基於集合的方法,只需指定需要執行的操作。使用這種方法要做的事情就是,指定你想通過查詢獲得的結果的條件和要求。在檢索數據過程中,你不需要關註實現查詢的內部機制:資料庫引擎會決定最佳的執行查詢的演算法和邏輯。

由於 SQL 是基於集合的,所以這種方法比起程式方法更加有效,這也解釋了為什麼在某些情況下,SQL 可以比代碼工作地更快。

基於集合的查詢方法也是數據挖掘分析行業要求你必須掌握的技能!因為你需要熟練的在這兩種方法之間進行切換。如果你發現自己的查詢中存在程式查詢,則應該考慮是否需要重寫這部分。

 

從查詢到執行計劃 

反向模式不是靜止不變的。在你成為 SQL 開發者的過程中,避免查詢反向模型和重寫查詢可能會是一個很艱難的任務。所以時常需要使用工具以一種更加結構化的方法來優化你的查詢。

對性能的思考不僅需要更結構化的方法,還需要更深入的方法。

然而,這種結構化和深入的方法主要是基於查詢計劃的。查詢計劃首先被解析為“解析樹”並且準確定義了每個操作使用什麼演算法以及如何協調操作過程。

 

查詢優化

在優化查詢時,很可能需要手動檢查優化器生成的計劃。在這種情況下,將需要通過查看查詢計劃來再次分析你的查詢。

要掌握這樣的查詢計劃,你需要使用一些資料庫管理系統提供給你的工具。你可以使用以下的一些工具:

  • 一些軟體包功能工具可以生成查詢計劃的圖形表示。
  • 其它工具能夠為你提供查詢計劃的文本描述。

請註意,如果你正在使用 PostgreSQL,則可以區分不同的 EXPLAIN,你只需獲取描述,說明 planner 如何在不運行計劃的情況下執行查詢。同時 EXPLAIN ANALYZE 會執行查詢,並返回給你一個評估查詢計劃與實際查詢計劃的分析報告。一般來說,實際執行計劃會切實的執行這個計劃,而評估執行計劃可以在不執行查詢的情況下,解決這個問題。在邏輯上,實際執行計劃更為有用,因為它包含了執行查詢時,實際發生的其它細節和統計信息。

接下來你將瞭解 XPLAIN 和 ANALYZE 的更多信息,以及如何使用這兩個命令來進一步瞭解你的查詢計劃和查詢性能。要做到這一點,你需要開始使用兩個表: one_million 和 half_million 來做一些示例。

你可以藉助 EXPLAIN 來檢索 one_million 表的當前信息:確保已將其放在運行查詢的首要位置,在運行完成之後,會返回到查詢計劃中:

EXPLAIN
SELECT *
FROM one_million;
QUERY PLAN
_________________________________________________
Seq Scan on one_million
(cost=0.00..18584.82 rows=1025082 width=36)
(1 row)

在以上示例中,我們看到查詢的 Cost 是0.00..18584.82 ,行數是1025082,列寬是36。

同時,也可以藉助 ANALYZE 來更新統計信息  。

ANALYZE one_million;
EXPLAIN
SELECT *
FROM one_million;
QUERY PLAN
_________________________________________________ Seq Scan on one_million (cost=0.00..18334.00 rows=1000000 width=37) (1 row)

除了 EXPLAIN 和 ANALYZE,你也可以藉助 EXPLAIN ANALYZE 來檢索實際執行時間:

EXPLAIN ANALYZE
SELECT *
FROM one_million;
QUERY PLAN
___________________________________________________
Seq Scan on one_million
(cost=0.00..18334.00 rows=1000000 width=37)
(actual time=0.015..1207.019 rows=1000000 loops=1)
Total runtime: 2320.146 ms
(2 rows)

使用 EXPLAIN ANALYZE 的缺點就是需要實際執行查詢,這點值得註意!

到目前為止,我們看到的所有演算法是順序掃描或全表掃描:這是一種在資料庫上進行掃描的方法,掃描的表的每一行都是以順序(串列)的順序進行讀取,每一列都會檢查是否符合條件。在性能方面,順序掃描不是最佳的執行計劃,因為需要掃描整個表。但是如果使用慢磁碟,順序讀取也會很快。

還有一些其它演算法的示例:

EXPLAIN ANALYZE
SELECT *
FROM one_million JOIN half_million
ON (one_million.counter=half_million.counter);
QUERY PLAN
_____________________________________________________________
Hash Join (cost=15417.00..68831.00 rows=500000 width=42)
(actual time=1241.471..5912.553 rows=500000 loops=1)
Hash Cond: (one_million.counter = half_million.counter)
    -> Seq Scan on one_million
    (cost=0.00..18334.00 rows=1000000 width=37)
    (actual time=0.007..1254.027 rows=1000000 loops=1)
    -> Hash (cost=7213.00..7213.00 rows=500000 width=5)
    (actual time=1241.251..1241.251 rows=500000 loops=1)
    Buckets: 4096 Batches: 16 Memory Usage: 770kB
    -> Seq Scan on half_million
    (cost=0.00..7213.00 rows=500000 width=5)
(actual time=0.008..601.128 rows=500000 loops=1)
Total runtime: 6468.337 ms

我們可以看到查詢優化器選擇了 Hash Join。請記住這個操作,因為我們需要使用這個來評估查詢的時間複雜度。我們註意到了上面示例中沒有 half_million.counter 索引,我們可以在下麵示例中添加索引  :

CREATE INDEX ON half_million(counter);
EXPLAIN ANALYZE
SELECT *
FROM one_million JOIN half_million
ON (one_million.counter=half_million.counter);
QUERY PLAN
______________________________________________________________
Merge Join (cost=4.12..37650.65 rows=500000 width=42)
(actual time=0.033..3272.940 rows=500000 loops=1)
Merge Cond: (one_million.counter = half_million.counter)
    -> Index Scan using one_million_counter_idx on one_million
    (cost=0.00..32129.34 rows=1000000 width=37)
    (actual time=0.011..694.466 rows=500001 loops=1)
    -> Index Scan using half_million_counter_idx on half_million
    (cost=0.00..14120.29 rows=500000 width=5)
(actual time=0.010..683.674 rows=500000 loops=1)
Total runtime: 3833.310 ms
(5 rows)

通過創建索引,查詢優化器已經決定了索引掃描時,如何查找 Merge join。

請註意,索引掃描和全表掃描(順序掃描)之間的區別:後者(也稱為“表掃描”)是通過掃描所有數據或索引所有頁面來查找到適合的結果,而前者只掃描表中的每一行。

 

教程的第二部分內容,就介紹到這裡。後續還會有《如何編寫更好的SQL查詢》系列的最後一篇文章,敬請期待。

原文鏈接:http://www.kdnuggets.com/2017/08/write-better-sql-queries-definitive-guide-part-2.html

轉載請註明出自:葡萄城控制項

 

相關閱讀:

【報表福利大放送】100餘套報表模板免費下載

如何編寫更好的SQL查詢:終極指南-第一部分

一句SQL完成動態分級查詢

遷移 SQL Server 資料庫到 Azure SQL 實戰

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、父組件向子組件傳遞參數 2、子組件向父組件傳遞參數 ...
  • 轉載無源頭地址 在這篇文章中,將比較深入地闡述下執行上下文 – JavaScript中最基礎也是最重要的一個概念。相信讀完這篇文章後,你就會明白javascript引擎內部在執行代碼以前到底做了些什麼,為什麼某些函數以及變數在沒有被聲明以前就可以被使用,以及它們的最終的值是怎樣被定義的。 什麼是執行 ...
  • 之前讀過一篇關於“什麼是全棧設計師”的文章,裡面提到所謂的全棧設計師就是能做線框圖、原型圖,能做視覺稿,能寫前後端代碼。放到產品設計中,全棧設計師就是能一個人搞定產品開發的所有環節。其中,最原始、最關鍵的一個環節就是線框或者說原型設計。這個環節的意義就相當於上層建築的扎實地基。那麼打造地基的工具很重 ...
  • 昨天剛裝的Genymotion,昨晚還用得好好的。 今晚開機,重新打開Genymotion,卻提示:"Unable to connect to the Genymotion server. Please check your Internet connection."。 看提示,我以為是網路問題,分 ...
  • 一、前沿||潛心修心,學無止盡。生活如此,coding亦然。本人鳥窩,一隻正在求職的鳥。聯繫我可以直接微信:jkxx123321 二、項目總結 **||**文章參考資料:1. http://blog.csdn.net/u011272795/article/details/73824558 2.htt ...
  • 一般情況,在- (void)webViewDidFinishLoad:(UIWebView *) webView方法里添加如下代碼: 這方法有時候會失效! 這方法在沒有改變webview的字體大小的時候還是使用正常的,但是你在改了字體大小或者圖片大小等之後是沒有效果的, webview的高度還是原來 ...
  • USE master; --5.2 字元串函數 --1.計算字元串長度 SELECT LEN('abc'); --2.字元串轉換為小寫 SELECT 'A', LOWER('a'); --3.字元串轉換為大寫 SELECT 'a', UPPER('a'); --4.截去字元串左側空格 SELECT ... ...
  • 轉自: http://www.maomao365.com/?p=4906 <span style="color:white;background-color:blue;font-weight:bold;">一、instead of 觸發器應用一創建只讀視圖的方法</span><span style= ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...