簡體   English   中英

高效的MySQL查詢大量數據

[英]Efficient MySQL query for huge set of data

說我有一個如下表:

CREATE TABLE `hadoop_apps` (
  `clusterId` smallint(5) unsigned NOT NULL,
  `appId` varchar(35) COLLATE utf8_unicode_ci NOT NULL,
  `user` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
  `queue` varchar(35) COLLATE utf8_unicode_ci NOT NULL,
  `appName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `submitTime` datetime NOT NULL COMMENT 'App submission time',
  `finishTime` datetime DEFAULT NULL COMMENT 'App completion time',
  `elapsedTime` int(11) DEFAULT NULL COMMENT 'App duration in milliseconds',
  PRIMARY KEY (`clusterId`,`appId`,`submitTime`),
  KEY `hadoop_apps_ibk_finish` (`finishTime`),
  KEY `hadoop_apps_ibk_queueCluster` (`queue`,`clusterId`),
  KEY `hadoop_apps_ibk_userCluster` (`user`(8),`clusterId`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

mysql> SELECT COUNT(*) FROM hadoop_apps;

這會給我一個計數158593816

因此,我試圖了解以下查詢的效率低下以及如何改進它。

mysql> SELECT * FROM hadoop_apps WHERE DATE(finishTime)='10-11-2013';

另外,這兩個查詢有什么區別?

mysql> SELECT * FROM hadoop_apps WHERE user='foobar';
mysql> SELECT * FROM hadoop_apps HAVING user='foobar';

WHERE DATE(finishTime)='10-11-2013';

這對優化器來說是個問題,因為只要您將列放入這樣的函數中,優化器就不會知道該函數返回的值的順序是否與輸入到該函數的值的順序相同。 因此,它不能使用索引來加快查找速度。

要解決此問題,請不要將列放在這樣的函數調用中,如果您希望針對該列的查找使用索引。

另外,您應該使用MySQL標准日期格式:YYYY-MM-DD。

WHERE finishTime BETWEEN '2013-10-11 00:00:00' AND '2013-10-11 23:59:59'

[WHERE和HAVING子句中的條件]有什么區別?

WHERE子句用於過濾行。

HAVING子句用於應用GROUP BY 之后過濾結果。

請參閱SQL-在何處使用VS

如果WHERE有效,則優先於HAVING 前者是在處理的早期完成的,因此減少了要挖掘的數據量。 好的,在您的一個示例中,它們之間可能沒有區別。

每當我在UNIQUE鍵(您的PK)中看到DATETIME時,我都會畏縮。 應用程序不能在同一秒內有兩行嗎? 這是您要承擔的風險嗎?

即使更改為DATETIME(6) (微秒)也可能會有風險。

無論您在該領域做什么,我都建議使用以下模式進行測試:

WHERE finishTime >= '2013-10-11'
  AND finishTime  < '2013-10-11' + INTERVAL 1 DAY

對於DATEDATETIMEDATETIME(6)等,它可以“正確”運行。其他類型的聲音會增加一個額外的午夜或錯過一秒鍾的時間。 如果間隔超過一天,它可以避免麻煩日等麻煩。

KEY `hadoop_apps_ibk_userCluster` (`user`(8),`clusterId`)

不好。 它不會超過user(8) 像這樣的前綴通常是沒有用的。 讓我們看看誘使您構建該鍵的查詢; 我們會提出一個更好的方案。

1.58億行帶有4個varchars。 它們聽起來像沒有很多不同價值的價值嗎? 建立查找表,並將其替換為SMALLINT UNSIGNED (2個字節,0..64K范圍)或其他小的id。 這將顯着縮小表,從而使其更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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