【发布时间】:2017-01-30 06:23:55
【问题描述】:
我在对大型物理表(1.7GB,2300 万行)进行查询时遇到优化问题,我们称之为 p_table。
我需要使用 p_table 的主索引选择数千行。我的第一次尝试是使用主索引进行 IN 查询,例如
SELECT * FROM p_table WHERE primary_key IN (111,222,333,[... 60.000 more]).
由于查询速度非常慢(50-60 秒),我决定通过使用内存引擎将所有主键添加到临时表中来优化它,然后按如下方式加入
CREATE TEMPORARY TABLE tmp_table (primary_key BIGINT(20) NOT NULL PRIMARY KEY) ENGINE=Memory;
INSERT IGNORE INTO t_table VALUES(111),(222),(333),[thousandsmore];
SELECT p.* FROM p_table AS p FORCE INDEX(PRIMARY) INNER JOIN tmp_table AS t FORCE INDEX(PRIMARY) ON t.primary_key = g.primary_key;
此解决方案加快了 x4 的查询,但仍会导致服务器负载很大,每次查询大约需要 10-20 秒(取决于临时表的大小)。
查询的解释表明它没有使用索引,即使我强制它们。
["id"]=>
string(1) "1"
["select_type"]=>
string(6) "SIMPLE"
["table"]=>
string(1) "t"
["type"]=>
string(3) "ALL"
["possible_keys"]=>
string(7) "PRIMARY"
["key"]=>
NULL
["key_len"]=>
NULL
["ref"]=>
NULL
["rows"]=>
string(4) "64320"
["Extra"]=>
string(0) ""
不幸的是,整个数据库超过 50GB,这意味着我买不起完整的内存数据库,而且像 p_table 这样的大表依赖于磁盘 I/O。
您对如何优化流程有什么建议吗?还有关于为什么没有使用索引的任何提示(或者更有可能没有由 EXPLAIN 显示)?
服务器信息: Debian 8.6 mysql 5.5.53 8GB 内存 Raid0 中的 SSD 磁盘(它是 Slave 之一,Raid10 在 Master 上)
非常感谢
【问题讨论】:
标签: mysql database optimization