1

我在运行使用 MyISAM 数据库的 SQL 查询时面临性能问题。

简而言之,我有 3 个表:
表:A(引擎 MyISAM。总记录:1847)
表:B(引擎 MyISAM。总记录:1110)
表:C(引擎 MyISAM。总记录:57867)

现在我正在运行的查询需要 623 秒才能执行,有时会发生来自服务器的连接(与 localhost 的情况相同)被中止。

以下是我正在执行的查询:

SELECT MATCH(A.title, A.description) AGAINST('Computer Graphic Artist') AS 'Score',
    A.code AS 'Code',
    B.cluster AS 'Cluster',
    B.pathway AS 'Pathway',
    A.title AS 'Role',
    A.description AS 'Description'
FROM B
INNER JOIN A ON B.code = A.code
INNER JOIN C ON B.code = C.code
WHERE MATCH(A.title, A.description) AGAINST('Computer Graphic Artist')
  OR MATCH(B.cluster, B.pathway, B.descripton) AGAINST('Computer Graphic Artist')
  OR MATCH(C.title) AGAINST('Computer Graphic Artist')
ORDER BY Score DESC, B.cluster ASC

您也可以参考Pastie(如果您看不到这条 SQL)。我在适用的地方添加了 FULLTEXT 属性。

注意:表 A、B 和 C 也很少有重复记录。

请告诉我,如何优化此 SQL 以实现快速输出。

4

1 回答 1

0

首先要做的是确保在从每个表中查询的确切列集上都有一个 FULLTEXT 索引:

alter table A add fulltext index a_fti (title,description);
alter table B add fulltext index b_fti (cluster, pathway, descripton);
alter table C add fulltext index c_fti (title);

然后我建议重写您的查询以使用 UNION 而不是 OR。我从 FULLTEXT 搜索中获得了更好的性能,特别是在 MySQL 中使用这种方法。

这是使用您的查询的示例:

select Score, Code, Cluster, Pathway, Role, Description
from
(
SELECT MATCH(A.title, A.description) AGAINST('Computer Graphic Artist') AS 'Score',
    A.code AS 'Code',
    B.cluster AS 'Cluster',
    B.pathway AS 'Pathway',
    A.title AS 'Role',
    A.description AS 'Description'
FROM B
INNER JOIN A ON B.code = A.code
INNER JOIN C ON B.code = C.code
WHERE MATCH(A.title, A.description) AGAINST('Computer Graphic Artist')
UNION
SELECT MATCH(A.title, A.description) AGAINST('Computer Graphic Artist') AS 'Score',
    A.code AS 'Code',
    B.cluster AS 'Cluster',
    B.pathway AS 'Pathway',
    A.title AS 'Role',
    A.description AS 'Description'
FROM B
INNER JOIN A ON B.code = A.code
INNER JOIN C ON B.code = C.code
WHERE MATCH(B.cluster, B.pathway, B.descripton) AGAINST('Computer Graphic Artist')
UNION
SELECT MATCH(A.title, A.description) AGAINST('Computer Graphic Artist') AS 'Score',
    A.code AS 'Code',
    B.cluster AS 'Cluster',
    B.pathway AS 'Pathway',
    A.title AS 'Role',
    A.description AS 'Description'
FROM B
INNER JOIN A ON B.code = A.code
INNER JOIN C ON B.code = C.code
WHERE MATCH(C.title) AGAINST('Computer Graphic Artist')
) as sub_query
ORDER BY Score DESC, Cluster ASC
于 2012-07-20T14:45:14.510 回答