① 復雜慢sql語句如何優化
很簡單啊,優先索引,第二結構,第三演算法。
索引最簡單,如果是SQL server客戶端或者toad可以提示有哪些需要進行優化的地方。
結構就是針對要查詢的值,盡量集中到一個表,減少串表,函數查詢,左鏈的表欄位查詢。
演算法就是OR還是IN?串表時IN還是EXISTS ?oracle in 的限制。條件執行順序等。
然後還有其他注意的,例如只查固定欄位就不要 select * 只要注意以上步驟,千萬級數據串10個秒也能1秒內顯示出來。
有條件的話,當然是用歸檔數據進行查詢,這樣就不會佔用業務數據IO了,最後一步就是「雲計算」(解析有一百種,沒有統一概念,我的意識其實就是歸檔過程中根據分組維度計算好,並根據日期放進相關的表,減少表粒度,只進行簡單的select查詢)
② 《資料庫查詢優化器的藝術原理解析與SQL性能優化》epub下載在線閱讀,求百度網盤雲資源
《資料庫查詢優化器的藝術》(李海翔)電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:
書名:資料庫查詢優化器的藝術
作者:李海翔
豆瓣評分:8.4
出版社:機械工業出版社
出版年份:2014-1-1
頁數:532
內容簡介:
《資料庫技術叢書·資料庫查詢優化器的藝術:原理解析與SQL性能優化》是資料庫查詢優化領域的里程碑之作,由Oracle公司MySQL全球開發團隊、資深專家撰寫,作者有10餘年資料庫內核和查詢優化器研究經驗。資料庫領域泰斗王珊教授親自作序推薦,PostgreSQL中國社區和中國用戶會發起人以及來自Oracle、新浪、網易、華為等企業的數位資深資料庫專家聯袂推薦。從原理角度深度解讀和展示資料庫查詢優化器的技術細節和全貌;從源碼實現角度全方位深入分析MySQL和PostgreSQL兩大主流開源資料庫查詢優化器的實現原理;從工程實踐的角度對比了兩大資料庫的查詢優化器的功能異同和實現異同。它是所有數據開發工程師、內核工程師、DBA以及其他資料庫相關工作人員值得反復研讀的一本書。
《資料庫技術叢書·資料庫查詢優化器的藝術:原理解析與SQL性能優化》共19章,分為四個部分:第一篇(第1~4章)對資料庫查詢優化技術的范圍、邏輯查詢優化、物理查詢優化,以及查詢優化器與其他模塊的關系做了非常細致、深入的講解;第二篇(第5~10章)首先從源碼角度對PostgreSQL查詢優化器的架構、層次、設計思想、相關數據結構和實現原理進行了深入、系統的分析,然後從功能角度對PostgreSQL的邏輯查詢優化、物理查詢優化、查詢優化器的關鍵演算法,以及PostgreSQL查詢優化器與其他模塊的關系做了深入的講解;第三篇(第11~16章)首先從源碼角度對MySQL查詢優化器的架構、層次、設計思想、相關數據結構和實現原理進行了深入、系統的分析,然後從功能角度對MySQL的邏輯查詢優化、物理查詢優化、查詢優化器的關鍵演算法,以及MySQL查詢優化器與其他模塊的關系做了深入的講解;第四篇(第17~19章)對PostgreSQL與MySQL的邏輯查詢優化技術、物理查詢優化技術、設計思想和編碼規范等各方面進行了深度的比較。
作者簡介:
李海翔,網名「那海藍藍」,資深資料庫專家,從事資料庫研發、資料庫測試與技術管理等工作10餘年,對資料庫的內核有深入的研究,長於PostgreSQL和MySQL等開源資料庫的內核與架構。現任職於Oracle公司MySQL全球開發團隊,從事查詢優化技術的研究和MySQL查詢優化器的開發工作。曾參與了863、核高基、工信部、科技部、發改委、北京市科委等多個重大科技項目。2005年獲得北京市科學技術進步獎一等獎,2006年獲高級工程師(系統分析師)。
③ DBA必備的23款最佳SQL管理工具,精選
因為市場上有許多的SQL管理工具,所以要為SQL項目管理選擇工具是一件有挑戰性的事。為大家推薦23款SQL工具的精選列表,希望朋友們喜歡。其中幾款已經在昨天的SQL查詢優化工具一文中,做過推薦。
Aqua Data Studio是一個功能豐富的通用SQL集成開發環境(IDE),它使資料庫開發人員,DBA和數據/業務分析人員能夠從單個界面開發,管理和分析30多個平台的數據。
特徵:
dbForge Studio for SQL Server是一個功能強大的IDE,用於SQL Server管理,管理,開發,數據報告,分析等等。執行復雜資料庫任務的SQL開發人員和DBA可以使用GUI工具來加速幾乎所有資料庫體驗,例如設計資料庫,編寫SQL代碼,比較資料庫,同步模式和數據,生成有意義的測試數據等等。
特徵:
dbWatch是一個完整的資料庫監控和管理解決方案,適用於SQL Server,Oracle,PostgreSQL,Sybase,MySQL和Azure。專為在大型內部部署,混合或雲資料庫環境中進行主動管理和日常維護自動化而設計。
特徵:
Jet Profiler for MySQL是MySQL資料庫伺服器的實時查詢性能和診斷工具。該工具自2009年開發,非常穩定。
特徵:
Adminer是一個用於管理資料庫,表,關系,索引和用戶的SQL管理工具。它支持所有流行的資料庫管理系統,如MySQL,PostgreSQL,SQLite,MS SQL,Oracle和MongoDB。
特徵:
它是一種用於分析微軟SQL Server資料庫結構差異的SQL管理工具。它允許比較資料庫對象,如表,列,索引,外鍵,模式等。
特徵:
EMS SQL Manager允許用戶創建和編輯SQL Server資料庫對象,並創建,修改,執行和保存SQL查詢。
特徵:
它是一個基於JAVA的資料庫管理工具。這種符合JDBC的SQL管理工具允許用戶查看資料庫結構並發出SQL命令。它還支持Firebird,微軟Access,微軟SQL Server,MySQL,Oracle,Sybase等資料庫。
特徵:
SQLite Database Browser是一個開源SQL工具,允許用戶創建,設計和編輯SQLite資料庫文件。它允許用戶顯示由它們和應用本身發出的所有SQL命令的日誌。
特徵:
DBeaver是一個面向開發人員和資料庫管理員的開源資料庫工具。它支持JDBC兼容的資料庫,如MySQL,Oracle,IBM DB2,SQL Server,Firebird,SQLite和Sybase。
特徵:
DbVisualizer Free是一個SQL管理工具。它允許用戶管理各種資料庫,包括Oracle,Sybase,SQL Server,MySQL,Informix,H3和SQLite。
特徵:
HeidiSQL是另一種可靠的SQL管理工具。它使用流行的MySQL伺服器,微軟SQL資料庫和PostgreSQL設計。它允許用戶瀏覽和編輯數據,創建和編輯表,視圖,觸發器和預定事件。
特徵:
FlySpeed SQL Query是所有資料庫用戶和開發人員的數據處理工具。它允許用戶在不熟悉SQL語法的情況下在不同的資料庫伺服器上構建查詢。
特徵:
SQL Diagnostic Manager是Idera開發的性能監控工具。它提供診斷解決方案,幫助用戶評估其SQL Server中的運行狀況和性能。
特徵:
ManageEngine開發的免費SQL性能監控工具。它允許用戶密切關注SQL Server性能!此工具還可以幫助用戶監控SQL Server的性能和可用性。它可以與MS SQL 2012和2014等所有MS SQL版本一起使用。
特徵:
ApexSQL Monitor是一個基於Web的SQL管理應用程序。它為監控多個SQL Server實例提供支持。
特徵:
適用於微軟SQL Server的AppDynamics資料庫管理產品的一種全面SQL工具。它用於監控SQL Server的2000,2005,2008,2012和2014版本。
特徵:
Toad是另一個SQL Server DBMS工具。它通過廣泛的自動化,直觀的工作流程和內置的專業知識最大化了生產力。此SQL管理工具可解決問題,管理更改並提升最高級別的代碼質量。
特徵:
Zenoss提供ZenPacks來管理微軟SQL Server,MySQL,Oracle資料庫和PostgreSQL。每個ZenPack都具有每個平台的特定功能,並提供可用的API來確定應監控的內容。
特徵:
Lepide的SQL Server Storage Manager是一個用於分析SQL Server性能的開源實用程序。它提供了對存儲空間和性能的完全可視性。
特徵:
SQL Server Management Studio Express是一個用於訪問,管理和開發SQL所有組件的開源工具。此工具支持SQL Server的大多數管理任務。
特徵:
SolarWinds Database Performance Analyzer是用於資料庫管理的性能監視和分析工具。它還找出了瓶頸的原因並降低了資料庫操作的總體成本。
特徵:
Sequel Pro是一款快速,易用的資料庫管理工具,適用於MySQL。此SQL管理工具有助於與資料庫進行交互。使用此軟體添加新資料庫,添加新表,添加新行和任何其他類型的資料庫也很容易。
特徵:
④ 如何優化SQL語句
一、問題的提出
在應用系統開發初期,由於開發資料庫數據比較少,對於查詢SQL語句,復雜視圖的的編寫等體會不出SQL語句各種寫法的性能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中數據的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是SQL語句的優化。對於海量數據,劣質SQL語句和優質SQL語句之間的速度差別可以達到上百倍,可見對於一個系統不是簡單地能實現其功能就可,而是要寫出高質量的SQL語句,提高系統的可用性。
在多數情況下,Oracle使用索引來更快地遍歷表,優化器主要根據定義的索引來提高性能。但是,如果在SQL語句的where子句中寫的SQL代碼不合理,就會造成優化器刪去索引而使用全表掃描,一般就這種SQL語句就是所謂的劣質SQL語句。在編寫SQL語句時我們應清楚優化器根據何種原則來刪除索引,這有助於寫出高性能的SQL語句。
二、SQL語句編寫注意問題
下面就某些SQL語句的where子句編寫中需要注意的問題作詳細介紹。在這些where子句中,即使某些列存在索引,但是由於編寫了劣質的SQL,系統在運行該SQL語句時也不能使用該索引,而同樣使用全表掃描,這就造成了響應速度的極大降低。
1.
IS
NULL
與
IS
NOT
NULL
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。
任何在where子句中使用is
null或is
not
null的語句優化器是不允許使用索引的。
2.
聯接列
對於有聯接的列,即使最後的聯接值為一個靜態值,優化器是不會使用索引的。我們一起來看一個例子,假定有一個職工表(employee),對於一個職工的姓和名分成兩列存放(FIRST_NAME和LAST_NAME),現在要查詢一個叫比爾.柯林頓(Bill
Cliton)的職工。
下面是一個採用聯接查詢的SQL語句,
select
*
from
employss
where
first_name||''||last_name
='Beill
Cliton';
上面這條語句完全可以查詢出是否有Bill
Cliton這個員工,但是這里需要注意,系統優化器對基於last_name創建的索引沒有使用。
當採用下面這種SQL語句的編寫,Oracle系統就可以採用基於last_name創建的索引。
***
where
first_name
='Beill'
and
last_name
='Cliton';
.
帶通配符(%)的like語句
同樣以上面的例子來看這種情況。目前的需求是這樣的,要求在職工表中查詢名字中包含cliton的人。可以採用如下的查詢SQL語句:
select
*
from
employee
where
last_name
like
'%cliton%';
這里由於通配符(%)在搜尋詞首出現,所以Oracle系統不使用last_name的索引。在很多情況下可能無法避免這種情況,但是一定要心中有底,通配符如此使用會降低查詢速度。然而當通配符出現在字元串其他位置時,優化器就能利用索引。在下面的查詢中索引得到了使用:
select
*
from
employee
where
last_name
like
'c%';
4.
Order
by語句
ORDER
BY語句決定了Oracle如何將返回的查詢結果排序。Order
by語句對要排序的列沒有什麼特別的限制,也可以將函數加入列中(象聯接或者附加等)。任何在Order
by語句的非索引項或者有計算表達式都將降低查詢速度。
仔細檢查order
by語句以找出非索引項或者表達式,它們會降低性能。解決這個問題的辦法就是重寫order
by語句以使用索引,也可以為所使用的列建立另外一個索引,同時應絕對避免在order
by子句中使用表達式。
5.
NOT
我們在查詢時經常在where子句使用一些邏輯表達式,如大於、小於、等於以及不等於等等,也可以使用and(與)、or(或)以及not(非)。NOT可用來對任何邏輯運算符號取反。下面是一個NOT子句的例子:
...
where
not
(status
='VALID')
如果要使用NOT,則應在取反的短語前面加上括弧,並在短語前面加上NOT運算符。NOT運算符包含在另外一個邏輯運算符中,這就是不等於(<>)運算符。換句話說,即使不在查詢where子句中顯式地加入NOT詞,NOT仍在運算符中,見下例:
...
where
status
<>'INVALID';
對這個查詢,可以改寫為不使用NOT:
select
*
from
employee
where
salary<3000
or
salary>3000;
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。
⑤ 資料庫系統優化的人工智慧自動SQL優化
人工智慧自動SQL優化出現在90年代末。目前在商用資料庫領域,LECCO Technology Limited(靈高科研有限公司)擁有該技術,並提供使用該技術的自動優化產品LECCO SQL Expert,它支持Oracle、Sybase、MS SQL Server和IBM DB2資料庫平台。該產品針對資料庫應用的開發和維護階段提供的模塊有:SQL語法優化器、PL/SQL集成化開發調試環境(IDE)、掃描器、資料庫監視器等。其核心模塊SQL 語法優化器的工作原理為:①輸入一條源SQL語句;②「人工智慧反饋式搜索引擎」對輸入的SQL語句,結合檢測到的資料庫結構和索引進行重寫,產生N條等效的SQL語句輸出;③產生的N條等效SQL語句再送入「人工智慧反饋式搜索引擎」進行重寫,直至無法產生新的輸出或搜索限額滿;④對輸出的SQL語句進行過濾,選出具有不同執行計劃的SQL語句;⑤對得到的SQL語句進行批量測試,找出性能最好的SQL語句。
⑥ SQL執行與優化
SQL優化
執行計劃,表關聯查詢順序,優化策略與思路
下面再向前走一些,容我根據自己的認識說一下查詢執行的流程是怎樣的:
1.連接
1.1客戶端發起一條Query請求,監聽客戶端的『連接管理模塊』接收請求
1.2將請求轉發到『連接進/線程模塊』
1.3調用『用戶模塊』來進行授權檢查
1.4通過檢查後,『連接進/線程模塊』從『線程連接池』中取出空閑的被緩存的連接線程和客戶端請求對接,如果失敗則創建一個新的連接請求
2.處理
2.1先查詢緩存,檢查Query語句是否完全匹配,接著再檢查是否具有許可權,都成功則直接取數據返回
2.2上一步有失敗則轉交給『命令解析器』,經過詞法分析,語法分析後生成解析樹
2.3接下來是預處理階段,處理解析器無法解決的語義,檢查許可權等,生成新的解析樹
2.4再轉交給對應的模塊處理
2.5如果是SELECT查詢還會經由『查詢優化器』做大量的優化,生成執行計劃
2.6模塊收到請求後,通過『訪問控制模塊』檢查所連接的用戶是否有訪問目標表和目標欄位的許可權
2.7有則調用『表管理模塊』,先是查看table cache中是否存在,有則直接對應的表和獲取鎖,否則重新打開表文件
2.8根據表的meta數據,獲取表的存儲引擎類型等信息,通過介面調用對應的存儲引擎處理
2.9上述過程中產生數據變化的時候,若打開日誌功能,則會記錄到相應二進制日誌文件中
3.結果
3.1Query請求完成後,將結果集返回給『連接進/線程模塊』
3.2返回的也可以是相應的狀態標識,如成功或失敗等
3.3『連接進/線程模塊』進行後續的清理工作,並繼續等待請求或斷開與客戶端的連接
接下來再走一步,讓我們看看一條SQL語句的前世今生。
首先看一下示例語句
示例語句
執行順序
SQL解析
1. FROM
當涉及多個表的時候,左邊表的輸出會作為右邊表的輸入,之後會生成一個虛擬表VT1。
(1-J1)笛卡爾積
計算兩個相關聯表的笛卡爾積(CROSS JOIN) ,生成虛擬表VT1-J1。
兩次全表掃描
哈希索引,查找復雜度都是 O(1) 。
2. WHERE
對VT1過程中生成的臨時表進行過濾,滿足WHERE子句的列被插入到VT2表中。
注意:
此時因為分組,不能使用聚合運算;也不能使用SELECT中創建的別名;
與ON的區別:
如果有外部列,ON針對過濾的是關聯表,主表(保留表)會返回所有的列;
如果沒有添加外部列,兩者的效果是一樣的;
應用:
對主表的過濾應該放在WHERE;
對於關聯表,先條件查詢後連接則用ON,先連接後條件查詢則用WHERE;
hash join 哈希連接 驅動表和被驅動表都只會訪問0次或1次
應用場景:一個大表一個小表/表上沒有索引/返回結果集比較大
3. GROUP BY
這個子句會把VT2中生成的表按照GROUP BY中的列進行分組。生成VT3表。
注意:
其後處理過程的語句,如SELECT,HAVING,所用到的列必須包含在GROUP BY中,對於沒有出現的,得用聚合函數;
原因:
GROUP BY改變了對表的引用,將其轉換為新的引用方式,能夠對其進行下一級邏輯操作的列會減少;
原作者的理解是:
根據分組欄位,將具有相同分組欄位的記錄歸並成一條記錄,因為每一個分組只能返回一條記錄,除非是被過濾掉了,而不在分組欄位裡面的欄位可能會有多個值,多個值是無法放進一條記錄的,所以必須通過聚合函數將這些具有多值的列轉換成單值;
GROUP BY 重新聚合查詢
4. HAVING
這個子句對VT3表中的不同的組進行過濾,只作用於分組後的數據,滿足HAVING條件的子句被加入到VT4表中。
7.LIMIT
LIMIT子句從上一步得到的VT6虛擬表中選出從指定位置開始的指定行數據。
注意:
offset和rows的正負帶來的影響;
當偏移量很大時效率是很低的,可以這么做:
採用子查詢的方式優化,在子查詢里先從索引獲取到最大id,然後倒序排,再取N行結果集
採用INNER JOIN優化,JOIN子句里也優先從索引獲取ID列表,然後直接關聯查詢獲得最終結果
當前未用到索引,
三次full scan , table1 AS a / table2 AS b / GROUP BY
盡量少做重復的工作
控制同一語句的多次執/減少多次的數據轉換/
杜絕不必要的子查詢和連接表,子查詢在執行計劃一般解釋成外連接,多餘的連接表帶來額外的開銷
關於臨時表和表變數的選擇
臨時表產生使用SELECT INTO和CREATE TABLE + INSERT INTO的選擇,一般情況下,SELECT INTO會比CREATE TABLE + INSERT INTO的方法快很多,但是SELECT INTO會鎖定TEMPDB的系統表SYSOBJECTS、SYSINDEXES、SYSCOLUMNS,在多用戶並發環境下,容易阻塞其他進程,所以建議,在並發系統中,盡量使用CREATE TABLE + INSERT INTO,而大數據量的單個語句使用中,使用SELECT INTO。
子查詢的用法
相關子查詢可以用IN、NOT IN、EXISTS、NOT EXISTS引入
NOT IN、NOT EXISTS的相關子查詢可以改用LEFT JOIN代替寫法
如果保證子查詢沒有重復 ,IN、EXISTS的相關子查詢可以用INNER JOIN 代替
IN``的相關子查詢用EXISTS代替
不要用 COUNT (*)的子查詢判斷是否存在記錄,最好用 LEFT` `JOIN 或者EXISTS,比如有人寫這樣的語句:
建立索引後,並不是每個查詢都會使用索引,在使用索引的情況下,索引的使用效率也會有很大的差別。只要我們在查詢語句中沒有強制指定索引,
不要對索引欄位進行運算,而要想辦法做變換
不要對索引欄位進行格式轉換
不要對索引欄位使用函數
不要對索引欄位進行多欄位連接
join關聯查詢的計算是很復雜的,特別是數據量比較大的情況下,實際情況還是拆解較快的
Join拆解的核心就是利用In關鍵字
要麼用空間換時間,要麼用時間換空間
多表連接的連接條件對索引的選擇有著重要的意義,所以我們在寫連接條件條件的時候需要特別注意。
A、多表連接的時候,連接條件必須寫全,寧可重復,不要缺漏。
B、連接條件盡量使用聚集索引
C、注意ON、WHERE和HAVING部分條件的區別
ON是最先執行, WHERE次之,HAVING最後,因為ON是先把不符合條件的記錄過濾後才進行統計,它就可以減少中間運算要處理的數據,按理說應該速度是最快的,WHERE也應該比 HAVING快點的,因為它過濾數據後才進行SUM,在兩個表聯接時才用ON的,所以在一個表的時候,就剩下WHERE跟HAVING比較了
考慮聯接優先順序:
(1)INNER JOIN
(2)LEFT JOIN (註:RIGHT JOIN 用 LEFT JOIN 替代)
(3)CROSS JOIN
索引並不適用於所有情況:a.少量數據;b.頻繁進行改動的欄位,不適合做索引;c.很少使用的欄位,不需要加索引
索引會提高數據查詢效率,但是會降低「增、刪、改」的效率。當不使用索引的時候,我們進行數據的增刪改,只需要操作源表即可,但是當我們添加索引後,不僅需要修改源表,也需要再次修改索引,很麻煩。
先執行順序, 是否走索引, 有無類型轉換
18000 字的SQL優化大全
步步深入:MySQL架構總覽->查詢執行流程->SQL解析順序
MySQL索引總結(4)——btree與hash區別
⑦ SQL優化(二)
SQL優化一: sql優化(一)
上片文章已經詳細介紹了explain各個欄位的含義,以及什麼情況應該建立索引,什麼情況不需要建立索引以及sql語句性能的判斷依據,接下來我介紹下如何合理的建立索引。
sql語句:select id,author_id from article where category_id = 1 and comments>1 order by views desc limit 1;
分析:首先我們根據where後面的條件建立符合索引,然後根據order by後面的欄位建立索引,因此建立索引idx_article_ccv,即以(category_id,comments,views)數據列建立復合索引,但由於comments是一個范圍,按照BTree索引的原理,先排序category_id,如果遇到相同的category_id則再排序comments,如果遇到相同的comments則再排序views,又因為comments欄位在復合索引里處於中間位置,而comments>1是一個條件(是一個范圍值),在復合索引的一個范圍值的數據列後面的索引全部失效,mysql無法利用索引再對後面的views部分進行檢索,也就是說views無法按照索引排序,所以explain下此sql語句,type為range,extra使用的是Using filesort,這是比較糟糕的。所以我們放棄comments這個范圍欄位,建立索引idx_article_cv,即以(category_id,views)數據列建立復合索引,explain 此sql,type變成了ref,extra的using filesort也變成了using index,這就變得好多了。
索引:idx_article_cv,即以(category_id,views)數據列建立復合索引
前段時間做了一個銷售精細化項目,是公司crm項目的一個大模塊,大致就是為銷售人員制定指標,實現銷售目標從區域到團到業務員到客戶,實時跟蹤業務員所負責客戶的下單量的情況。這就存在許多關聯關系,區域-團,團-業務員,業務員-客戶,這使得sql常常需要關聯多張表。
sql語句:SELECT
tu.fuserid,
tu.faccount,
tu.fphone,
tu.fcertificationtype,
tu.fcertificatename,
tu.fkeyarea,
tu.fkeyareatext,
DATE_FORMAT(tcr.fupdatetime,'%Y-%m-%d %H:%i:%s') as fupdatetime,
tag.forggroupid,
tag.forggroupname,
tug.forguserid,
tug.fusername,
tug.fuserphone,
tag.fcitycode
FROM t_finedt_user AS tu
LEFT JOIN t_finedt_customer_relation AS tcr
ON tu.fuserid = tcr.fuserid
LEFT JOIN t_finedt_usergroup AS tug
ON tcr.forguserid = tug.forguserid
and tcr.forggroupid = tug.forggroupid
LEFT JOIN t_finedt_areagroup AS tag
ON tug.forggroupid = tag.forggroupid
where tu.fkeyarea=? and tu.fuserid=? and tug.forggroupid = ?
分析:上面的sql是左連接,左邊的表一定是全表查詢,所以要建立右邊表對應關聯欄位的索引,在表t_finedt_user上建立tu_fuserid_fkeyarea索引,即以(fuserid,fkeyarea)欄位建立索引,在表t_finedt_customer_relation 上建立tcr_forguserid_forggroupid索引,即以(forguserid,forggroupid)欄位建立索引,在表t_finedt_usergroup 上建立tug_forguserid_forggroupid索引,即以(forguserid,forggroupid)欄位建立索引,在表t_finedt_areagroup上建立tag_forggroupid索引,即以(forggroupid)欄位建立索引。建立索引後,sql查詢速度明顯快了很多
索引:tcr_forguserid_forggroupid,tu_fuserid_fkeyarea,tug_forguserid_forggroupid,tag_forggroupid
1、盡可能減少join語句中的NestedLoop的循環次數,永遠用小結果集驅動大結果集
2、優先優化NestedLoop的內層循環
3、保證join語句總被驅動表上的join欄位已經被索引
4、當無法保證被驅動表join條件欄位被索引,且內存資源充足的前提下,不要太吝嗇joinBuffer的設置
1、全值匹配我最愛
2、最佳左前綴原則——如果索引了多列,要遵守最左前綴原則,指的是查詢從索引的最左前列開始並且不跳過索引中的列
3、並在索引列上做任何操作(計算、函數、自動or手動類型轉換),這些會導致索引失效而轉向全表掃描
4、存儲引擎不能使用索引中范圍條件右邊的列,范圍之後的索引全失效
5、盡量使用覆蓋索引(之訪問索引的查詢(索引列和查詢的列一致)),減少select *
6、mysql在使用不等於(!=、>、<)的時候無法使用索引會導致全表掃描。
7、is null、is not null也無法使用索引。
8、like以通配符開頭("%abc.."),mysql索引失效也會變成全表掃描的操作。
9、字元串不加單引號也會引起索引失效
10、少用or,用它來連接時會索引失效。
1、對於單值索引,盡量選擇針對當前query過濾性更好的索引
2、在選擇組合索引的時候,當前query中過濾性最好的欄位在索引欄位順序中,位置越靠前越好
3、在選擇組合索引的時候,盡量選擇盡可能包含當前query中的where字句中更多欄位的索引
4、盡可能通過分析統計信息和調整query的寫法來達到選擇合適索引的目的。
全值匹配我最愛,最左前綴要遵守
帶頭大哥不能死,中間兄弟不能斷
索引列上少計算,范圍之後全失效
like百分寫最右,覆蓋索引不寫里
不等空值還有or,索引失效要少用
var引號不可丟,sql高級也不難