【问题标题】:Optimization of a Virtuemart Attribute QueryVirtuemart 属性查询的优化
【发布时间】:2013-03-01 03:36:29
【问题描述】:

我在下面有一个选择查询,它的作用是从 Virtuemart 表中选择与某个属性匹配的所有产品。属性表相当大(将近 6000 行)。有什么方法可以优化下面的查询,或者有没有其他可能有用的过程,我已经尝试为一个甚至两个表添加索引。

SELECT DISTINCT `jos_vm_product`.`product_id`,
    `jos_vm_product_attribute`.`attribute_name`, 
    `jos_vm_product_attribute`.`attribute_value`,
    `jos_vm_product_attribute`.`product_id` 
FROM (`jos_vm_product`) 
    RIGHT JOIN `jos_vm_product_attribute` 
        ON `jos_vm_product`.`product_id` = `jos_vm_product_attribute`.`product_id`  
WHERE ((`jos_vm_product_attribute`.`attribute_name` = 'Size') 
    AND ((`jos_vm_product_attribute`.`attribute_value` = '6.5')  
        OR (`jos_vm_product_attribute`.`attribute_value` = '10')))    
GROUP BY `jos_vm_product`.`product_sku`   
ORDER BY CONVERT(`jos_vm_product_attribute`.`attribute_value`, SIGNED INTEGER)
LIMIT 0, 24

这是 EXPLAIN 表的结果:

id select_type table type possible_keys key key_len ref rows Extras 1 SIMPLE jos_vm_product_attribute range idx_product_attribute_name,attribute_value,attribute_name attribute_value 765 NULL 333 使用 where;使用临时的;使用文件排序 1 简单的 jos_vm_product eq_ref PRIMARY PRIMARY 4 shoemark_com_shop.jos_vm_product_attribute.product_id

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: mysql optimization


    【解决方案1】:

    jos_vm_product_attribute.attribute_name 索引替换为jos_vm_product_attribute.attribute_namejos_vm_product_attribute.attribute_value 上的复合索引(按此顺序)应该有助于此查询。目前,它仅使用WHERE 条件中的索引来表示jos_vm_product_attribute.attribute_value,但这个新索引将可用于WHERE 条件的两个部分。

    【讨论】:

    • 嗨,G-Nugget,感谢您的回复。我尝试按照您的建议进行操作,但出现以下错误:#1071 - 指定的密钥太长;最大密钥长度为 1000 字节
    • 编辑:实际上,我缩短了这两列的字符长度,然后重新运行 SQL alter table SQL 命令添加复合索引,它有效,没有发生错误。我会检查速度是否有差异。谢谢!
    • @TarunDhanwani 列的数据类型和字符集是什么?如果可能,您应该尝试完全索引列。如果您使用的是 utf-8 排序规则,这实际上会使索引中字段的长度增加三倍,这将使其更快地达到 1000 字节的限制。
    • 嗨,G-Nugget,它确实提高了一点速度,但是执行查询仍然需要一些时间。我有 4 列:attribute_id(int 11)、product_id(int 11)、attribute_name(char50) 和 attribute_value(char255)。所有列均已编入索引,并且 att_name 和 att_value 具有 utf-8 排序规则。我应该对这两列使用不同的排序规则吗?再次感谢。
    • @TarunDhanwani 请发布新的EXPLAINattribute_name 应该是 VARCHAR,除非每个值都是 50 个字符长。如果您知道您不会使用latin1 字符集之外的任何字符(您可能不会使用属性名称),那将是一个更好的选择。 attribute_value应该utf8,因为它是用户数据,你不想错过他们输入的任何内容。