2017-04-27 32 views
2

我正在MYSQL數據庫的一個非常大的表中運行廣告收入查詢。它包含許多維度,例如設備類別,日期,廣告客戶,垂直,creative_size,位置等,以及一些指標,如投放的展示次數,點擊次數和收入。加速對2GB的單個表的SQL查詢+

該表格用於顯示廣告效果,因此通常按一個或兩個維度進行分組並按維度進行過濾。

我已經把所有東西放在一張桌子上,以避免連接,並儘可能快,但由於尺寸的數量,廣告客戶,表格很大,已超過2.8Gb,並且正在增長。

我試圖索引和分區,但它仍然是非常慢的,所以我想通過一個更小的組維度對數據進行分組,而忽略了廣告欄創建一個較小的版本,即

Select date, creative_size, device_class,ssp,billing_type, location, 
     ad_impressions, clicks, revenue 
    from ADS 
group by date,creative_size,device_class,ssp,billing_type,location 

這會極大地減少行數。

我試圖用它作爲視圖,但它不是永久存儲的,所以需要更長的時間。我怎樣才能創建這樣一個表,並保持其基於另一個表的最新?我是否需要編寫腳本,或者是否可以使用一些內置的MySQL功能?這是一種可行的方法嗎?我很樂意接受其他解決方案:)

+0

如果您閱讀本文,這將有助於您獲得更好的答案,特別是有關查詢性能的部分。 http://meta.stackoverflow.com/a/271056/這個問題正處於堆棧溢出格式過於寬泛的邊緣。 –

+0

Ollie的好,但如果你需要更多的幫助,我們真的需要'SHOW CREATE TABLE'和實際的查詢。另外檢查一下這個小內存的'innodb_buffer_pool_size'大概是600M。 –

回答

3

你說的對,MySQL的VIEW對象無助於查詢性能。用行業術語來說,它們不是「物化視圖」。

您還沒有向我們披露您使用的實際查詢或您的大表的實際佈局。所以具體的建議是不可能的。

您有一些可能的方法來提高查詢性能。

  1. 正如您所建議的,從您的詳細表中生成一些聚合表。如果您能夠處理稍陳舊的數據,您可以在一夜之間重新生成它們。

  2. 如果您使用特定查詢,請調查創建compound covering indexes to accelerate those queries

看着你的問題中的查詢。首先,我想它應該有一些SUM項目,像這樣。我還將您提到的date更改爲DATE(date),以獲取摘要中的日期,而不是日期和時間。 (也許,在你的表的已經做了。如果是這樣,不要再這樣做。)

Select DATE(date), creative_size, device_class,ssp,billing_type, location, 
     SUM(ad_impressions), SUM(clicks), SUM(revenue) 
    from ADS 
group by DATE(date),creative_size,device_class,ssp,billing_type,location 

其次,這其中沒有任何WHERE條款。如果你添加WHERE子句,你(幾乎肯定)需要不同的複合覆蓋索引。你可以閱讀關於如何在別處使用WHERE子句的覆蓋索引。第三,這個查詢可以通過特定的複合索引來加速:GROUP BYSELECT子句中提到的所有列上的索引。 GROUP BY條款中的列應該位於索引中的第一位,通常與GROUP BY中的順序相同。你會創建這樣的索引。

CREATE INDEX summary_1 ON ADS 
       (date, creative_size, device_class,ssp,billing_type, location, 
       ad_impressions, clicks, revenue); 

這會有幫助,因爲MySQL的查詢規劃可通過索引順序讀,以滿足您的查詢,而不必遵循指向你的表。

第四,你可以做

CREATE TABLE ad_summary AS 
Select date, creative_size, device_class,ssp,billing_type, location, 
     SUM(ad_impressions), SUM(clicks), SUM(revenue) 
    from ADS 
group by date,creative_size,device_class,ssp,billing_type,location; 

這是一個窮人的物化視圖。 (如果你使用的是Oracle,你可以使用他們的物化視圖,我們稱之爲以前的富人的物化視圖-以前是因爲Oracle太貴了。)

第五,你可以日期限制你的彙總表如果這在你的應用程序中起作用)。通過在查詢中添加這樣的內容來實現這一點。

WHERE date >= CURDATE() - INTERVAL 7 DAY 

此特定WHERE子句可以使用覆蓋索引相同的化合物,因爲它確實上date的範圍內掃描,並且該列是首先在索引。

下面是關於研磨非常大的表的一些一般性觀察,供您考慮。

  • 許多像您這樣的表格上的單列索引通常會對性能造成不利影響。如果有的話,MySQL不會在單個查詢中的單個表中利用多個索引。
  • SELECT *肯定對性能有害,尤其是當您有很多列時。相反,列舉您需要的列。
  • 避免在大型查詢中使用ORDER BY子句,除非您知道您需要它們。
  • http://use-the-index-luke.com/是一個很好的參考,使這個東西很好的工作。
+0

[_More_](http://mysql.rjweb.org/doc.php/summarytables)彙總表。 –