Magento core_url_rewrite 零星表现
Magento core_url_rewrite sporadic performance
在我们的生产环境中,我注意到其中一个查询的性能偶尔会下降。
SELECT `core_url_rewrite`.*
FROM `core_url_rewrite`
WHERE (request_path IN (:path?, :path?, :path?, :path?))
AND (store_id IN(?, ?))
来自生产服务器的解释计划是:
id: 1
select_type: SIMPLE
table: core_url_rewrite
type: range
possible_keys: UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID,IDX_CORE_URL_REWRITE_STORE_ID
key: UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID
key_len: 770
ref: NULL
rows: 4
Extra: Using index condition
Mysql 版本:5.6.34。 Table 中的行数:473847。通常它在不到 1 毫秒内执行,但根据新遗迹的一些 Tx 是:最后 30 分钟内的 8.03 秒、5.35 秒、3.04 秒、2.97 秒、1.92 秒。
创建 Table 是:
CREATE TABLE `core_url_rewrite` (
`url_rewrite_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Rewrite Id',
`store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store Id',
`id_path` varchar(255) DEFAULT NULL COMMENT 'Id Path',
`request_path` varchar(255) DEFAULT NULL COMMENT 'Request Path',
`target_path` varchar(255) DEFAULT NULL COMMENT 'Target Path',
`is_system` smallint(5) unsigned DEFAULT '1' COMMENT 'Defines is Rewrite System',
`options` varchar(255) DEFAULT NULL COMMENT 'Options',
`description` varchar(255) DEFAULT NULL COMMENT 'Deascription',
`category_id` int(10) unsigned DEFAULT NULL COMMENT 'Category Id',
`product_id` int(10) unsigned DEFAULT NULL COMMENT 'Product Id',
PRIMARY KEY (`url_rewrite_id`),
UNIQUE KEY `UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID` (`request_path`,`store_id`),
UNIQUE KEY `UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID` (`id_path`,`is_system`,`store_id`),
KEY `IDX_CORE_URL_REWRITE_TARGET_PATH_STORE_ID` (`target_path`,`store_id`),
KEY `IDX_CORE_URL_REWRITE_ID_PATH` (`id_path`),
KEY `IDX_CORE_URL_REWRITE_STORE_ID` (`store_id`),
KEY `FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID` (`category_id`),
KEY `FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID` (`product_id`),
CONSTRAINT `FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID` FOREIGN KEY (`category_id`) REFERENCES `catalog_category_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID` FOREIGN KEY (`product_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CORE_URL_REWRITE_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=95984103 DEFAULT CHARSET=utf8 COMMENT='Url Rewrites'
(不是很确定,各种乱七八糟,还有几个问题……)
索引接近最优; EXPLAIN
表示它正在使用最佳索引。假设结果集没有返回数千行,我不得不冒险 猜测 这个查询不是坏人。
如果另一个查询是 运行ning(当这个查询很慢时),并且该查询经常命中此 table(可能是写入),那么它可能会变慢这个查询。 FK 增加了开销。
或者,另一个查询正在充斥 buffer_pool,将内容从缓存中冲出,导致 I/O.
突然飙升
或者,您有一百个连接都在积极地做某事,但没有很快完成。 (这是一个争夺资源的案例,每人获得一份'fair'份;没有人很快完成。)
使用 long_query_time=1
打开慢速日志并通过 pt-query-digest
或 mydumpslow -s t
进行总结将有助于找到竞争查询。
检查 RAM 大小并 innodb_buffer_pool_size
以查看后者占前者的很大一部分。 (如果它很小,那么 可能 导致 I/O 场景。)
顺便说一句,KEY(product_id)
对于以 product_id
开头的 3 列键是多余的。冗余键在 INSERT
.
上浪费时间
另外:您的 AUTO_INCREMENT
已达到 95M,即限制 (4B) 的 140/th。计算一下 - 你什么时候 运行 出来?同时,table 中只有 0.47M 行。这意味着使用 REPLACE
(可能有更好的替代)或 'burns' ids 的一些其他操作。请详细说明您的 INSERTs
.
一个解决方案(针对上一段)可能是摆脱 url_rewrite_id
并提升其中一个 UNIQUE
键以进行 PK。 (table 有 3 个有意义的唯一键的情况很少见。)提升有优点,但也有明显的缺点,因为 UNIQUE
都包含 VARCHAR(255)
。所以,我不打算推荐它还。
升级 this 查询正在使用的密钥将加快 this 查询的速度。
终于诊断出这个问题的原因,与mysql无关!
我们的 ulimit(默认值)较低,为 1024。我们将其更改为 65535。您可以使用以下命令进行检查:ulimit -n.
它是执行次数最多的查询之一,因此每当服务器上出现大量请求时,它就会开始等待。它不会出现在慢日志中,但新遗物将其捕获为慢查询。
在我们的生产环境中,我注意到其中一个查询的性能偶尔会下降。
SELECT `core_url_rewrite`.*
FROM `core_url_rewrite`
WHERE (request_path IN (:path?, :path?, :path?, :path?))
AND (store_id IN(?, ?))
来自生产服务器的解释计划是:
id: 1
select_type: SIMPLE
table: core_url_rewrite
type: range
possible_keys: UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID,IDX_CORE_URL_REWRITE_STORE_ID
key: UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID
key_len: 770
ref: NULL
rows: 4
Extra: Using index condition
Mysql 版本:5.6.34。 Table 中的行数:473847。通常它在不到 1 毫秒内执行,但根据新遗迹的一些 Tx 是:最后 30 分钟内的 8.03 秒、5.35 秒、3.04 秒、2.97 秒、1.92 秒。
创建 Table 是:
CREATE TABLE `core_url_rewrite` (
`url_rewrite_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Rewrite Id',
`store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store Id',
`id_path` varchar(255) DEFAULT NULL COMMENT 'Id Path',
`request_path` varchar(255) DEFAULT NULL COMMENT 'Request Path',
`target_path` varchar(255) DEFAULT NULL COMMENT 'Target Path',
`is_system` smallint(5) unsigned DEFAULT '1' COMMENT 'Defines is Rewrite System',
`options` varchar(255) DEFAULT NULL COMMENT 'Options',
`description` varchar(255) DEFAULT NULL COMMENT 'Deascription',
`category_id` int(10) unsigned DEFAULT NULL COMMENT 'Category Id',
`product_id` int(10) unsigned DEFAULT NULL COMMENT 'Product Id',
PRIMARY KEY (`url_rewrite_id`),
UNIQUE KEY `UNQ_CORE_URL_REWRITE_REQUEST_PATH_STORE_ID` (`request_path`,`store_id`),
UNIQUE KEY `UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID` (`id_path`,`is_system`,`store_id`),
KEY `IDX_CORE_URL_REWRITE_TARGET_PATH_STORE_ID` (`target_path`,`store_id`),
KEY `IDX_CORE_URL_REWRITE_ID_PATH` (`id_path`),
KEY `IDX_CORE_URL_REWRITE_STORE_ID` (`store_id`),
KEY `FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID` (`category_id`),
KEY `FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID` (`product_id`),
CONSTRAINT `FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID` FOREIGN KEY (`category_id`) REFERENCES `catalog_category_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CORE_URL_REWRITE_PRODUCT_ID_CATALOG_CATEGORY_ENTITY_ENTITY_ID` FOREIGN KEY (`product_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `FK_CORE_URL_REWRITE_STORE_ID_CORE_STORE_STORE_ID` FOREIGN KEY (`store_id`) REFERENCES `core_store` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=95984103 DEFAULT CHARSET=utf8 COMMENT='Url Rewrites'
(不是很确定,各种乱七八糟,还有几个问题……)
索引接近最优; EXPLAIN
表示它正在使用最佳索引。假设结果集没有返回数千行,我不得不冒险 猜测 这个查询不是坏人。
如果另一个查询是 运行ning(当这个查询很慢时),并且该查询经常命中此 table(可能是写入),那么它可能会变慢这个查询。 FK 增加了开销。
或者,另一个查询正在充斥 buffer_pool,将内容从缓存中冲出,导致 I/O.
突然飙升或者,您有一百个连接都在积极地做某事,但没有很快完成。 (这是一个争夺资源的案例,每人获得一份'fair'份;没有人很快完成。)
使用 long_query_time=1
打开慢速日志并通过 pt-query-digest
或 mydumpslow -s t
进行总结将有助于找到竞争查询。
检查 RAM 大小并 innodb_buffer_pool_size
以查看后者占前者的很大一部分。 (如果它很小,那么 可能 导致 I/O 场景。)
顺便说一句,KEY(product_id)
对于以 product_id
开头的 3 列键是多余的。冗余键在 INSERT
.
另外:您的 AUTO_INCREMENT
已达到 95M,即限制 (4B) 的 140/th。计算一下 - 你什么时候 运行 出来?同时,table 中只有 0.47M 行。这意味着使用 REPLACE
(可能有更好的替代)或 'burns' ids 的一些其他操作。请详细说明您的 INSERTs
.
一个解决方案(针对上一段)可能是摆脱 url_rewrite_id
并提升其中一个 UNIQUE
键以进行 PK。 (table 有 3 个有意义的唯一键的情况很少见。)提升有优点,但也有明显的缺点,因为 UNIQUE
都包含 VARCHAR(255)
。所以,我不打算推荐它还。
升级 this 查询正在使用的密钥将加快 this 查询的速度。
终于诊断出这个问题的原因,与mysql无关! 我们的 ulimit(默认值)较低,为 1024。我们将其更改为 65535。您可以使用以下命令进行检查:ulimit -n.
它是执行次数最多的查询之一,因此每当服务器上出现大量请求时,它就会开始等待。它不会出现在慢日志中,但新遗物将其捕获为慢查询。