簡體   English   中英

MySQL查詢和表優化

[英]MySql query and table optimisation

我試圖在具有500K條記錄的表上運行以下簡單查詢。

SELECT COUNT(*) AS impressionCount
            FROM impression
            WHERE 0 = 0
                AND impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120'
                AND impressionObjectId2 = '1';

該查詢需要10秒鍾才能運行。 我已經嘗試為impressionObjectId1和impressionObjectId2列創建單獨的索引,以及使用這兩者的復合索引。 復合材料在一段時間內效果很好,但現在也很慢。

這是我的表結構:

DROP TABLE IF EXISTS `impression`;
CREATE TABLE `impression` (
  `impressionId` varchar(50) NOT NULL,
  `impressionObjectId1` varchar(50) NOT NULL,
  `impressionObjectId2` varchar(50) default NULL,
  `impressionStampDate` datetime NOT NULL,
  PRIMARY KEY  (`impressionId`),
  KEY `IX_object` (`impressionObjectId1`,`impressionObjectId2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC COMMENT='InnoDB free: 191488 kB';

任何建議將不勝感激。 謝謝

編輯:添加一個解釋時,這是輸出:

1, 'SIMPLE', 'impression', 'ref', 'IX_object', 'IX_object', '105', 'const,const', 304499, 'Using where; Using index'

如果您要反復運行該確切查詢,則可以緩存結果。 每次您插入帶有impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120' AND impressionObjectId2 = '1'的表, impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120' AND impressionObjectId2 = '1'增加一個計數器,並且每次刪除時,都會減少該計數器。

如果您要查詢的uniqe案例數量相對較少,那么這將是一個很好的性能提升器,盡管它對數據完整性不是那么好,並且必須謹慎使用。

在為VARCHAR字段創建索引時,使用col_name(X)語法僅在前X個字符上創建索引通常會有所幫助。

假設字段的前X個字符足以區分行(取決於那里的數據類型),則索引以這種方式更有效。 如果您的列包含GUID(如示例第1列)或很短的文本(如第2列),則僅為前10個字符創建索引確實可以提高性能。

我在您的解釋中注意到,您的“ ROWS”值非常高。 您的結果集中應包含多少行? (請注意,解釋中的ROWS是查找結果集所必須搜索的行數,而不是結果集中的行數)

您有可能可以顛​​倒索引的順序並獲得一定的效率。

通常,您希望將最有選擇性的列放在索引的第一位,以使可能的匹配行數最小。

這是找到最有選擇性的列的一個好技巧:

SELECT SUM(impressionObjectId1 = 'C69A54B8-B828-E2E4-2319A93011DF4120'),
       SUM(impressionObjectId2 = '1')
            FROM impression;

選擇性最高的列將具有最低的SUM值。 將該列放在索引的第一位。

您也可以只創建2個索引,一個創建另一個索引,然后讓MySQL選擇最佳索引。

暫無
暫無

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

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