在两个联合(UNION ALL)巨大的表中提高SELECT性能

时间:2016-12-31 19:25:38

标签: mysql union

我有两个巨大的表,需要执行以下查询。表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 

有关改进此查询/结构的任何建议吗?

1 个答案:

答案 0 :(得分:2)

尝试将GROUP BY CONCAT(fname, lname)更改为GROUP BY fname, lname。完成所有这些连接是额外的工作,这是不必要的。

这两者之间唯一的语义差异是,如果有两个人的名字和姓氏不同,但在连接时它们是相同的,例如,弗雷达史密斯和弗雷德阿斯米斯。这种组合可能不太可能,我怀疑你真的希望它们首先被合并为一个结果。

如果您按照您选择的同一组列进行分组,则只需使用

SELECT DISTINCT fname, lname

您可以使用UNION DISTINCT代替UNION ALL,因为您需要删除重复项。然后,您不需要在外部查询中进行分组或DISTINCT