【发布时间】:2016-03-23 23:03:49
【问题描述】:
自从我开始使用 MariaDB 10 以来,我就遇到了这个问题。查询花费了太多时间。使用 MySql 5.5,他们最多需要一分钟才能获得结果集,但使用 MariaDB,我什至无法在 20 分钟后看到结果集。
这个系统在 Magento 1.7.0.2 上运行,但这个问题与 Magento 无关,所以我没有在 Magento 部分下创建它。
我的服务器管理员说“服务器上一切正常,查询在 ram 上运行,并且当这个查询开始运行时,cpu 是 100%,如果你想改进它,你需要更改查询或增加 cpu 功率。 ”。但我很确定这与 MariaDB 和/或数据库服务器设置有关。
如果有人之前遇到过这样的问题,请引导我走正确的道路。
这是应该运行的最大查询之一,以获取用于创建提要的数据。
SELECT `e`.*, `at_status`.`value` AS `status`, `at_visibility`.`value` AS
`visibility`, `at_quality_score`.`value` AS `quality_score`,
`at_exportable_for_idealo`.`value` AS `exportable`,
`stock`.`qty`, `stock`.`is_in_stock`, `stock`.`manage_stock`,
`stock`.`use_config_manage_stock`, `stock`.`min_qty`,
`stock`.`min_sale_qty`, MAX(DISTINCT request_path) AS `request_path`,
`cpsl`.`parent_id`, `categories`.*, `categories_parent`.*,
GROUP_CONCAT(DISTINCT categories_index.category_id) AS `categories_ids`,
`price_index`.`min_price`, `price_index`.`max_price`,
`price_index`.`tier_price`, `price_index`.`final_price` FROM
`catalog_product_entity` AS `e`
INNER JOIN `catalog_product_website` AS `product_website` ON
product_website.product_id = e.entity_id AND product_website.website_id =
'1'
INNER JOIN `catalog_product_entity_int` AS `at_status` ON
(`at_status`.`entity_id` = `e`.`entity_id`) AND (`at_status`.`attribute_id`
= '96') AND (`at_status`.`store_id` = 0)
INNER JOIN `catalog_product_entity_int` AS `at_visibility` ON
(`at_visibility`.`entity_id` = `e`.`entity_id`) AND
(`at_visibility`.`attribute_id` = '102') AND (`at_visibility`.`store_id` =
0)
INNER JOIN `catalog_product_entity_varchar` AS `at_quality_score` ON
(`at_quality_score`.`entity_id` = `e`.`entity_id`) AND
(`at_quality_score`.`attribute_id` = '313') AND
(`at_quality_score`.`store_id` = 0)
INNER JOIN `catalog_product_entity_int` AS `at_exportable_for_idealo` ON
(`at_exportable_for_idealo`.`entity_id` = `e`.`entity_id`) AND
(`at_exportable_for_idealo`.`attribute_id` = '353') AND
(`at_exportable_for_idealo`.`store_id` = 0)
LEFT JOIN `cataloginventory_stock_item` AS `stock` ON
stock.product_id=e.entity_id
LEFT JOIN `core_url_rewrite` AS `url` ON url.product_id=e.entity_id AND
url.target_path NOT LIKE '%category%' AND is_system=1 AND ISNULL(options)
AND url.store_id=1
LEFT JOIN `catalog_product_super_link` AS `cpsl` ON
cpsl.product_id=e.entity_id
LEFT JOIN `catalog_category_product` AS `categories` ON
categories.product_id=e.entity_id
LEFT JOIN `catalog_category_product` AS `categories_parent` ON
categories_parent.product_id=cpsl.parent_id
LEFT JOIN `catalog_category_product_index` AS `categories_index` ON
((categories_index.category_id=categories.category_id AND
categories_index.product_id=categories.product_id) OR
(categories_index.category_id=categories_parent.category_id AND
categories_index.product_id=categories_parent.product_id )) AND
categories_index.store_id=1
LEFT JOIN `catalog_product_index_price` AS `price_index` ON
price_index.entity_id=e.entity_id AND customer_group_id=0 AND
price_index.website_id=1 WHERE (at_status.value = '1') AND (`e`.`type_id`
IN('simple')) AND (at_visibility.value IN('1')) AND (`e`.`attribute_set_id`
IN('19', '13', '4')) AND ((at_quality_score.value = 'A')) AND
((at_status.value = '1')) AND ((at_exportable_for_idealo.value = '1'))
如前所述,即使 20 分钟后我也看不到结果!没有抛出异常,没有 sql 错误日志,没有 php 错误日志,什么都没有。即使我直接在 PhpMyAdmin 上运行它,结果也是完全一样的。
提前致谢。
【问题讨论】:
-
如果您的 dba 说:“它在 RAM 中运行” - 他不是 DBA。他应该说(如果一切正常)- 查询在索引上运行,优化路径看起来很正常……至于查询本身——太可怕了。任何不是索引的 JOIN 都应该在 WHERE 子句中,而不是在 FROM 中 - 这是可怕的 SQL
-
是否创建了所有必要的索引?这(索引)占用 RAM...也许您的管理员不会说在创建索引后它在 RAM 中运行...缺少索引可能会对性能产生指数级影响。
-
感谢您的 cmets,也许我不得不提一下,这些查询是针对同一系统上不同提要的选定字段动态创建的。这就是让它们像单独的内部连接的原因。 Ram 主题也可以正常使用,因为查询被缓存在 RAM 上以便以后更快地访问它们。我的问题的解决方案是更改缓冲逻辑并在一个查询中使用更少的行,而不是一次全部使用它们。使用提到的优化,sql 查询仍然可以更快地工作。再次感谢 cmets。
-
使用
MAX和GROUP_CONCAT以及一些非聚合列而没有GROUP BY本质上是“错误的”。 -
请为该查询提供
EXPLAIN SELECT ...,为每个表提供SHOW CREATE TABLE。