簡體   English   中英

優化大表的簡單SQL查詢

[英]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解決方案。

所以:

  1. 為SmallTable1(id)創建索引
  2. 為SmallTable2(id)創建索引
  3. 為LargeTable(id1)和LargeTable(id2)創建索引

重要提示 :您可以同時為一個以上的列創建索引,例如LargeTable(id1,id2)<---請勿這樣做,因為這對您而言沒有意義。

接下來 ,您的查詢不是開箱即用的錯誤,但是它沒有遵循最佳實踐查詢。 關系數據庫基於Set理論 因此,您必須考慮“裝有大理石的袋子”而不是“桌子中的單元格”。 大致而言,您的初始查詢可轉換為:

  1. 從LargeTable c,SmallTable1 a和SmallTable2 b獲得一切
  2. 現在,當您擁有所有這些信息時,請找到以下項目:c.id1 = a.id AND c.id2 = b.id; (您需要花費5秒鍾以上的時間,因為這是半資源密集型的)

Ambrish建議使用正確的查詢,盡管不會更快。

為什么? 因為最后,您仍然將表中的所有數據從數據庫中拉出。

至於數據本身,1000萬條記錄雖然不是一個大表,但也不小。 在數據倉庫中, 星型模式是一個標准。 而且您基本上有一個星型架構。 您實際面臨的問題是必須實時計算結果,這需要時間。 我之所以告訴您,是因為在公司環境中,工程師每天都在面對這些問題。 解決方案是OLAP(基本上是預先計算,預先匯總,預先匯總,預先所有的數據)。 然后,最終用戶只查詢此預先計算的數據,查詢看起來非常快,但是它永遠不會100%正確,因為OLTP(在線事務處理=日常數據庫)和OLAP(在線分析 )之間存在延遲處理=報告數據庫)索引將幫助處理WHERE id = 3等查詢。但是,當您進行交叉聯接並從數據庫中基本提取所有內容時,它可能不會在您的案例中發揮重要作用。

因此,簡而言之:如果您唯一的選擇是查詢,那么將很難進行改進。

在一種情況下,對大表中的ID1ID2分別進行索引將減少差異。 如果有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM