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

Mysql 连接两个大表时的性能问题,mysql,sql,performance,optimization,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`

我有一个多语言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
和products表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
这需要永远。 任何优化此查询/表的帮助都将不胜感激。
谢谢。

尝试将翻译表的结构更改为:

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\u CALC\u FOUND\u行,我不明白为什么您需要翻译项的计数器 您可以在第一个查询之后运行另一个查询:

SELECT COUNT(*) FROM products;

我敢肯定,您会对性能感到惊讶:-

谢谢您的回答,但不幸的是,这没有帮助。问题是“订单依据”条款。此查询加上一些“where”参数需要55秒,如果不进行排序,只需1.4秒。您真的需要按文本字段排序吗?是的,我需要向用户提供筛选和排序选项,按字母顺序排序是一个基本的请求,但在大多数情况下,您可以将类型更改为VARCHAR。我最长的一行包含23K字节的文本,我尝试将它们转换为varchar10k,然后执行时间增加了5!时代。我在这里找到了答案: