为初学者优化MySQL查询(添加索引,重写查询,使用解释等)?

时间:2013-12-21 16:32:38

标签: php mysql sql

我正在查看慢查询日志并运行查询解释,现在我该如何解释输出以进行改进?

示例:

EXPLAIN SELECT corecountry, corestatus 
        FROM daydream_ddvalpha.propcore 
        WHERE corecountry = '7'    AND corestatus >= '100'

<小时/> 的输出:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'propcore', 'ALL', NULL, NULL, NULL, NULL, '1532', 'Using where'

<小时/> 显示索引:

SHOW INDEX FROM daydream_ddvalpha.propcore = 
# Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment, Index_comment
'propcore', '0', 'PRIMARY', '1', 'coreref', 'A', '1773', NULL, NULL, ”, 'BTREE', ”, ”

说明:

describe daydream_ddvalpha.propcore
# Field, Type, Null, Key, Default, Extra
'coreref', 'varchar(10)', 'NO', 'PRI', '', ''
'coretitle', 'varchar(75)', 'NO', '', '', ''
'coreprice', 'int(25) unsigned', 'NO', '', '0', ''
'corecurr', 'tinyint(1)', 'NO', '', '0', ''
'coreagent', 'varchar(10)', 'NO', '', '0', ''
'corebuild', 'smallint(4)', 'NO', '', '0', ''
'coretown', 'varchar(25)', 'NO', '', '', ''
'coreregion', 'varchar(25)', 'NO', '', '', ''
'corecountry', 'smallint(4)', 'NO', '', '0', ''
'corelocation', 'smallint(4)', 'NO', '', '0', ''
'corestatus', 'smallint(4)', 'NO', '', '0', ''
'corelistsw', 'char(1)', 'NO', '', '', ''
'corepstatus', 'tinyint(4)', 'NO', '', '0', ''
'coreseq', 'mediumint(10)', 'NO', '', '0', ''
'coreviews', 'mediumint(10)', 'NO', '', '0', ''
'coreextract', 'char(1)', 'NO', '', 'n', ''

编辑:新示例

我发现了一个更复杂的查询:

EXPLAIN SELECT coreref, coretitle, coreprice, corecurr, corebuild, coretown,    corecountry, corepstatus, corestatus FROM daydream_ddvalpha.propcore 

    WHERE coretown = 'Torrepacheco' 

    AND corestatus >= '100'

    ORDER BY coreprice ASC

    LIMIT 135, 10

输出:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'propcore', 'ALL', NULL, NULL, NULL, NULL, '1579', 'Using where; Using    filesort'

我理解第一个关于索引的例子的答案,但是这个怎么样?我应该创建一个索引来覆盖coretown和corestatus以及coreprice。我得到的印象是,我最终会得到许多带有重复值的索引,或者这是正常的吗?

1 个答案:

答案 0 :(得分:2)

这是您的查询:

SELECT corecountry, corestatus
FROM daydream_ddvalpha.propcore
WHERE corecountry = '7' AND corestatus >= '100'

where子句中有两个条件。一个是平等,一个不是。有帮助的索引是daydream_ddvalpha.propcore(corecountry, corestatus)corecountry必须先行,因为相等条件必须是索引中最左边的列。然后你会得到一个不等式,即corecountry

您只选择这两个字段。上述索引被称为查询的覆盖索引,因为查询所需的所有列都在索引中。换句话说,只读取查询的索引,而不是原始数据。

作为注释:如果字段是数字,那么您不需要在值周围加上引号。使用单引号使它们看起来像字符串,这有时会混淆SQL优化器和阅读代码的人。

编辑:

如评论中所述,添加索引的语法是:

create index idx_propcore_country_status ON propcore(corecountry, corestatus);

我通常将索引命名为表的名称,后跟列(但名称可以是任何有效的标识符)。