【发布时间】:2017-05-15 15:14:07
【问题描述】:
我有两个巨大的表,需要执行以下查询。表authors_1(~20M 行)和authors_2(~120M 行)具有相同的结构。我已经完成了研究并提出了以下查询和表结构。查询仍然需要很长时间(通常在 10 到 20 秒之间)。
这是查询:
SELECT `fname`, `lname`
FROM (
SELECT `fname`, `lname`
FROM `authors_1`
WHERE 1 AND `lname` LIKE 'AR%'
UNION ALL
SELECT `fname`, `lname`
FROM `authors_2`
WHERE 1 AND `lname` LIKE 'AR%') `a`
GROUP BY CONCAT(`fname`, `lname`)
ORDER BY `lname`
LIMIT 0, 999;
这是两个表的结构相似(FT 索引用于其他查询)。
CREATE TABLE `scipers_authors` (
`a_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`linker` varchar(255) COLLATE utf8_persian_ci NOT NULL,
`fname` tinytext COLLATE utf8_persian_ci NOT NULL, /*Should this be tinytext because of FT index or I can use VARCHAR(255) while having FT index?*/
`lname` tinytext COLLATE utf8_persian_ci NOT NULL, /*Same for this one*/
PRIMARY KEY (`a_id`),
UNIQUE KEY `linker` (`linker`) USING BTREE,
KEY `lname_4` (`lname`(4)) USING BTREE,
KEY `name` (`lname`(128),`fname`(128)) USING BTREE,
FULLTEXT KEY `fname` (`fname`),
FULLTEXT KEY `lname` (`lname`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci;
这是上面显示的示例查询的EXPLAIN 输出(我不知道如何使它漂亮like others,我正在使用PMA):
1 PRIMARY <derived2> ALL 476968 Using temporary; Using filesort
2 DERIVED authors_1 range lname_4,name,lname name 386 184800 Using where
3 UNION authors_2 range lname_4,name,lname name 386 292168 Using where
UNION RESULT <union2,3> ALL Using temporary
对改进这个查询/结构有什么建议吗?
【问题讨论】:
-
我认为您不需要
lname_4索引,因为它是name索引的前缀。请注意,改为使用name索引。有多少行满足LIKE条件? -
将 GROUP BY CONCAT(
fname,lname) 改为 GROUP BYfname,lname然后mysql可以使用索引(如果有的话) -
+1 表示
I've done my researches and came up....进行研究之前询问 SO 总是一个好兆头:-)。并且还显示EXPLAIN。 -
@Barmar,对于给定的查询,它大约有 320K 行。我认为
lname_4可以提供帮助,因为它只索引了前 4 个字母。 -
B-tree 索引可用于优化索引的任何前缀。所以前缀的另一个索引是多余的。