mysql - 或者在 MySQL 中使查询非常慢

标签 mysql sql magento

我在 MySQL 中有一个针对 magento 的大型查询,这需要花费很多时间。我试图优化它,但我的 MySQL 知识不足以解决它,所以也许有人可以看一下并给我一些正确方向的提示。

Select Distinct
  `e`.*,
  `cat_index`.`position` AS `cat_index_position`,
  `price_index`.`price`,
  `price_index`.`tax_class_id`,
  `price_index`.`final_price`,
  IF(price_index.tier_price IS NOT NULL, 
      LEAST(price_index.min_price, price_index.tier_price),
      price_index.min_price) AS `minimal_price`,
  `price_index`.`min_price`,
  `price_index`.`max_price`,
  `price_index`.`tier_price`
From
  `catalog_product_entity` AS `e`
    Inner Join
  `catalog_category_product_index` As `cat_index`
    On cat_index.product_id=e.entity_id And
       cat_index.store_id=1 And
       cat_index.visibility In(2, 4) And
       cat_index.category_id='2'
    Inner Join
  `catalog_product_index_price` AS `price_index` 
    On price_index.entity_id = e.entity_id And
       price_index.website_id = '1' And
       price_index.customer_group_id = 0
    Left Join
  `beta_entity_product` AS `beta` 
    On e.entity_id = beta.product_id And
       beta.entity_id In (81558, 81559, ... stupidly long list of ids)
    Left Join 
  `catalog_product_entity_int` AS `is_uni` 
    On e.entity_id = is_uni.entity_id And
       attribute_id = 179 
Where 
 is_uni.value = 1 OR 
 beta.product_id IS NOT NULL

如果我在 WHERE 子句中只有 1 个条件,一切都很好,但是使用 OR 有时需要几分钟才能完成,那太长了。我必须选择哪些选项才能获得更好的结果?另一个问题是我无法从中进行更多查询,只能将结果连接在一起。一切都必须在 1 个查询中。

当我对查询执行 EXPLAIN 时,我得到以下结果(以 JSON 格式复制以便更好地了解):

{
        "data":
        [
            {
                "id": 1,
                "select_type": "SIMPLE",
                "table": "e",
                "type": "ALL",
                "possible_keys": "PRIMARY",
                "key": null,
                "key_len": null,
                "ref": null,
                "rows": 213396,
                "Extra": "Using temporary"
            },
            {
                "id": 1,
                "select_type": "SIMPLE",
                "table": "beta",
                "type": "range",
                "possible_keys": "PRIMARY",
                "key": "PRIMARY",
                "key_len": "4",
                "ref": null,
                "rows": 2833,
                "Extra": "Using where; Using index"
            },
            {
                "id": 1,
                "select_type": "SIMPLE",
                "table": "is_uni",
                "type": "ref",
                "possible_keys": "UNQ_CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID,IDX_CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID,IDX_CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID",
                "key": "UNQ_CATALOG_PRODUCT_ENTITY_INT_ENTITY_ID_ATTRIBUTE_ID_STORE_ID",
                "key_len": "6",
                "ref": "unc_cpk.e.entity_id,const",
                "rows": 1,
                "Extra": "Using where"
            },
            {
                "id": 1,
                "select_type": "SIMPLE",
                "table": "cat_index",
                "type": "eq_ref",
                "possible_keys": "PRIMARY,IDX_CAT_CTGR_PRD_IDX_PRD_ID_STORE_ID_CTGR_ID_VISIBILITY,15D3C269665C74C2219037D534F4B0DC",
                "key": "PRIMARY",
                "key_len": "10",
                "ref": "const,unc_cpk.e.entity_id,const",
                "rows": 1,
                "Extra": "Using where"
            },
            {
                "id": 1,
                "select_type": "SIMPLE",
                "table": "price_index",
                "type": "eq_ref",
                "possible_keys": "PRIMARY,IDX_CATALOG_PRODUCT_INDEX_PRICE_CUSTOMER_GROUP_ID,IDX_CATALOG_PRODUCT_INDEX_PRICE_WEBSITE_ID",
                "key": "PRIMARY",
                "key_len": "8",
                "ref": "unc_cpk.cat_index.product_id,const,const",
                "rows": 1,
                "Extra": "Using where"
            }
        ]
    }

最佳答案

有多种解决方案:

1) 拆分查询并使用 UNION - 可能的排序和分页问题 2) 添加仅用于此过滤器的新属性,而不是

is_uni.value = 1 或 beta.product_id 不为空

你只会查询

feature_filter = 1

3) 将查询分解为多个查询 - 我建议这是第一步,因为像这样大的查询真的是搬起石头砸自己的脚

顺便说一句。对这么多列的查询使用 distinct 会消耗大量资源(mysql 需要比较每个列的值!)

关于mysql - 或者在 MySQL 中使查询非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13423247/

相关文章:

mysql - 更改时间执行限制

mysql - SQL - 获取名称而不是 ID

mysql - 我有两个选择,我希望结果表是两个选择的并集

.net - sp 执行时阻止读取行

php - 如何解决magento1.9.1.0这个错误

mysql - 将数据类型从 bigint 更改为 tinyint 形成具有外键引用的现有表

Mysql:从转储表中标记插入的行

sql - SQL 查询中的游标

database - Magento:关于产品图片(小图、拇指图等)的信息,在数据库中的什么位置?

Magento 1.8 自定义模块 404