[英]Optimizing simple SQL query for large table
我有一個查詢,其中一個表具有約1000萬行,而另兩個在每個表中均小於20。
SELECT a.name, b.name, c.total
FROM smallTable1 a, smallTable2 b, largeTable c
WHERE c.id1 = a.id AND c.id2 = b.id;
largeTable
具有列(id, id1, id2, total)
largeTable
1000萬行
smallTable1
具有列(id, name)
smallTable2
具有列(id, name)
現在需要5秒鍾才能運行。
是否可以使其更快?
創建索引-它們是查詢快速的原因。 沒有索引,我們將只能使用CPU解決方案。
所以:
重要提示 :您可以同時為一個以上的列創建索引,例如LargeTable(id1,id2)<---請勿這樣做,因為這對您而言沒有意義。
接下來 ,您的查詢不是開箱即用的錯誤,但是它沒有遵循最佳實踐查詢。 關系數據庫基於Set理論 。 因此,您必須考慮“裝有大理石的袋子”而不是“桌子中的單元格”。 大致而言,您的初始查詢可轉換為:
Ambrish建議使用正確的查詢,盡管不會更快。
為什么? 因為最后,您仍然將表中的所有數據從數據庫中拉出。
至於數據本身,1000萬條記錄雖然不是一個大表,但也不小。 在數據倉庫中, 星型模式是一個標准。 而且您基本上有一個星型架構。 您實際面臨的問題是必須實時計算結果,這需要時間。 我之所以告訴您,是因為在公司環境中,工程師每天都在面對這些問題。 解決方案是OLAP(基本上是預先計算,預先匯總,預先匯總,預先所有的數據)。 然后,最終用戶只查詢此預先計算的數據,查詢看起來非常快,但是它永遠不會100%正確,因為OLTP(在線事務處理=日常數據庫)和OLAP(在線分析 )之間存在延遲處理=報告數據庫)索引將幫助處理WHERE id = 3等查詢。但是,當您進行交叉聯接並從數據庫中基本提取所有內容時,它可能不會在您的案例中發揮重要作用。
因此,簡而言之:如果您唯一的選擇是查詢,那么將很難進行改進。
在一種情況下,對大表中的ID1
和ID2
分別進行索引將減少差異。 如果有9,000,000行ID1
匹配SmallTable1.id
行和200行ID2
匹配SmallTable2.id
的行,其中200行是同時存在的唯一行,那么您仍將進行幾乎完整的表/索引掃描。 如果是這樣的話,創建兩個索引ID1
和 ID2
應該加快速度,因為它可以然后找到那些200行與索引搜索。
如果可行,則可能需要在該索引中包括Total
,以使其成為該表的覆蓋索引。
該解決方案(假設它是一個)將非常以數據為中心,因此如果數據發生重大變化,則執行將發生變化。
無論您決定做什么,我建議您進行一次更改(創建索引或其他操作),然后檢查執行計划。 進行其他更改並檢查執行計划。 進行其他更改並檢查執行計划。 根據需要重復或倒帶。
使用連接而不是WHERE
子句
SELECT a.name, b.name, c.total
FROM smallTable1 a join largeTable c on c.id1 = a.id
join smallTable2 b on c.id2 = b.id;
並在largeTable(id1)
和largeTable(id2)
上創建index
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.