加入两个大表时的性能问题
Posted
技术标签:
【中文标题】加入两个大表时的性能问题【英文标题】:performance issue when joining two large tables 【发布时间】:2015-03-03 16:33:28 【问题描述】:我有一个多语言 CMS,它使用包含所有文本的翻译表(70k 行)
CREATE TABLE IF NOT EXISTS `translations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` int(11) NOT NULL,
`lang` int(11) NOT NULL,
`value` text CHARACTER SET utf8,
PRIMARY KEY (`id`),
KEY `key` (`key`,`lang`)
) ENGINE=MyISAM
和包含带有翻译键的产品的产品表(4k 行)
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name_trans_id` int(11) NOT NULL,
`desc_trans_id` int(11) DEFAULT NULL,
`text_trans_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_index` (`name_trans_id`),
KEY `desc_index` (`desc_trans_id`),
KEY `text_index` (`text_trans_id`)
) ENGINE=MyISAM
现在我需要按字母顺序获取前 20 个产品,为此我使用以下查询:
SELECT
SQL_CALC_FOUND_ROWS
dt_table.* ,
t_name.value as 'name'
FROM
products as dt_table
LEFT JOIN
`translations` as t_name on dt_table.name_trans_id = t_name.key
WHERE
(t_name.lang = 1 OR t_name.lang is null)
ORDER BY
name ASC LIMIT 0, 20
这需要永远。 任何优化此查询/表的帮助将不胜感激。 谢谢。
【问题讨论】:
【参考方案1】:尝试将translations
表的结构更改为:
CREATE TABLE IF NOT EXISTS `translations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` int(11) NOT NULL,
`lang` int(11) NOT NULL DEFAULT 0,
`value` text CHARACTER SET utf8,
PRIMARY KEY (`id`),
KEY `lang` (`lang`),
KEY `key` (`key`,`lang`),
FULLTEXT idx (`value`)
) ENGINE=InnoDB;
因为您确实需要在 WHERE
子句中使用 lang
时对其进行索引。
并尝试稍微更改您的查询:
SELECT
dt_table.* ,
t_name.value as 'name',
SUBSTR(t_name.value,0,100) as text_order
FROM
products as dt_table
LEFT JOIN (
SELECT key, value FROM `translations`
WHERE lang = 1 OR lang is null
) as t_name
ON dt_table.name_trans_id = t_name.key
ORDER BY
text_order ASC LIMIT 0, 20
如果你真的需要SQL_CALC_FOUND_ROWS
(我不明白你为什么需要翻译项目的柜台)
您可以在第一个查询之后立即运行另一个查询:
SELECT COUNT(*) FROM products;
我很确定你会对性能感到惊讶:-)
【讨论】:
感谢您的回答,但不幸的是它没有帮助。问题是“order by”子句。这个带有一些添加“where”参数的查询需要 55 秒,而没有应用排序时只需 1.4 秒 您真的需要按 TEXT 字段排序吗? 是的,我需要为用户提供过滤和排序选项,按字母顺序排序是基本要求 但大多数情况下您可以将类型更改为VARCHAR
我最长的行包含 23K 字节的文本,我尝试将它们转换为 varchar(10k),然后执行时间增加了 5!次。我在这里找到了答案:nicj.net/mysql-text-vs-varchar-performance以上是关于加入两个大表时的性能问题的主要内容,如果未能解决你的问题,请参考以下文章