你說的對,MySQL的VIEW對象無助於查詢性能。用行業術語來說,它們不是「物化視圖」。
您還沒有向我們披露您使用的實際查詢或您的大表的實際佈局。所以具體的建議是不可能的。
您有一些可能的方法來提高查詢性能。
正如您所建議的,從您的詳細表中生成一些聚合表。如果您能夠處理稍陳舊的數據,您可以在一夜之間重新生成它們。
如果您使用特定查詢,請調查創建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 BY
和SELECT
子句中提到的所有列上的索引。 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/是一個很好的參考,使這個東西很好的工作。
如果您閱讀本文,這將有助於您獲得更好的答案,特別是有關查詢性能的部分。 http://meta.stackoverflow.com/a/271056/這個問題正處於堆棧溢出格式過於寬泛的邊緣。 –
Ollie的好,但如果你需要更多的幫助,我們真的需要'SHOW CREATE TABLE'和實際的查詢。另外檢查一下這個小內存的'innodb_buffer_pool_size'大概是600M。 –