mysql - 连接两个大表时的性能问题

标签 mysql sql performance optimization

我有一个多语言 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

这需要永远。 任何优化此查询/表的帮助将不胜感激。 谢谢。

最佳答案

尝试将 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;

我很确定您会对性能感到惊讶:-)

关于mysql - 连接两个大表时的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28836984/

相关文章:

mysql - 从每个类别中选择几个小ID

javascript - 简化表单验证

php - WAMP Server V 2.5 图标为橙色,无响应且无菜单

php - 数组插入mysql行

SQL:替换每个名称的最后一年

sql - 加入后如何在两个 SQL 列之间放置一个空格?

java - 获取结果集() "should be called only once per result"

php - 为什么不必要的 IF 子句会提高性能?

performance - Haskell Vector 性能与 Scala 相比

javascript - php代码无法运行?没有错误信息