我的查询运行速度非常慢(约50秒):
SELECT SQL_NO_CACHE `main_table`.`entity_id`, `url_rewrite`.`request_path`
FROM `catalog_product_entity` AS `main_table`
INNER JOIN `catalog_product_website` AS `w`
ON main_table.entity_id = w.product_id
LEFT JOIN `core_url_rewrite` AS `url_rewrite`
ON url_rewrite.product_id = main_table.entity_id
AND url_rewrite.is_system = 1
AND url_rewrite.category_id IS NULL
AND url_rewrite.store_id = 1
AND url_rewrite.id_path LIKE 'product/%'
查询来自Magento,我只添加SQL_NO_CACHE
以使测量更准确。
如此长的执行时间当然是不可接受的。所以我转储了数据库并将其恢复到我的开发环境中以调查问题。但是在我的开发数据库中,查询非常快 - 它的运行时间不到0.1秒。
问题1: 在我的生产环境中如此长的执行时间可能是什么原因? 我还没有发现任何其他查询对我的生产数据库来说太慢了。
为了进一步调查我稍微修改了一下查询:
SELECT SQL_NO_CACHE `main_table`.`entity_id`, `url_rewrite`.`request_path`
FROM `catalog_product_entity` AS `main_table`
INNER JOIN `catalog_product_website` AS `w`
ON main_table.entity_id = w.product_id
LEFT JOIN `core_url_rewrite` AS `url_rewrite`
ON url_rewrite.product_id = main_table.entity_id
AND url_rewrite.is_system = 1
AND url_rewrite.category_id IS NULL
AND url_rewrite.store_id = 1
WHERE url_rewrite.id_path LIKE 'product/%'
(注意LIKE
表达式已转移到WHERE
子句
此查询返回相同的结果但更快 - 它在我的生产数据库上的执行时间不到1秒。
问题2:
为什么两个查询之间的执行时间有这么大差异? LIKE
子句中放置了LEFT JOIN
表达式是否存在任何问题?
EXPLAIN EXTENDED
的结果:生产数据库:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE w index PRIMARY IDX_CATALOG_PRODUCT_WEBSITE_WEBSITE_ID 2 NULL 642 100.00 Using index
1 SIMPLE main_table eq_ref PRIMARY PRIMARY 4 w.product_id 1 100.00 Using index
1 SIMPLE url_rewrite ref IDX_CORE_URL_REWRITE_ID_PATH, FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID 5 const 10 100.02
FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID,
FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID,
UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID
开发数据库:
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE w index PRIMARY IDX_CATALOG_PRODUCT_WEBSITE_WEBSITE_ID 2 NULL 1009 100.00 Using index
1 SIMPLE main_table eq_ref PRIMARY PRIMARY 4 w.product_id 1 100.00 Using index
1 SIMPLE url_rewrite ref IDX_CORE_URL_REWRITE_ID_PATH, FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID 5 w.product_id 31 100.00 Using where
FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID,
FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID,
UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID
表格大小(两台服务器上的相同,因为开发数据库是生产数据库的转储):
catalog_product_entity :
数据96 KB
指数88 KB
总计176 KB
catalog_product_website :
数据64 KB
索引16 KB
总计80 KB
core_url_rewrite :
数据5.5 MB
指数15.5 MB
总共21 MB
表记录计数(两个数据库都相同):
catalog_product_entity 1009
catalog_product_website 1009
core_url_rewrite 34878
当前时间表现:
生产数据库50秒
开发数据库0.1秒
所需时间
生产数据库1秒
开发数据库0.1秒
catalog_product_entity:
PRIMARY (entity_id,类型:BTREE,唯一:是)
IDX_CATALOG_PRODUCT_ENTITY_ENTITY_TYPE_ID (entity_type_id,类型:BTREE,唯一:否)
catalog_product_website:
PRIMARY (product_id,类型:BTREE,唯一:是)
IDX_CATALOG_PRODUCT_WEBSITE_WEBSITE_ID (website_id,类型:BTREE,唯一:否)
core_url_rewrite:
PRIMARY (url_rewrite_id,类型:BTREE,唯一:是)
UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID ((request_path,store_id),类型:BTREE,唯一:是)
UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID ((id_path,is_system,store_id),类型:BTREE,唯一:是)
IDX_CORE_URL_REWRITE_TARGET_PATH_STORE_ID ((target_path,store_id),类型:BTREE,唯一:否)
IDX_CORE_URL_REWRITE_ID_PATH (id_path,类型:BTREE,唯一:否)
IDX_CORE_URL_REWRITE_STORE_ID (store_id,类型:BTREE,唯一:否)
FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID (category_id,类型:BTREE,唯一:否)
FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID (product_id,类型:BTREE,唯一:否)
生产服务器没有太大的压力 - 我测试的所有其他查询在两个数据库上都给出了类似的结果。
我无法优化(更改)查询,因为它在系统中是硬编码的,但我想知道我的生产数据库发生了什么,这个查询比开发数据库慢得多。
我非常感谢解释MySQL的这种奇怪行为。