我们已经升级了数据库硬件,并从14.04升级到ubuntu 16.04。这附带了对mysql的更新。我们遇到了一些相当大的性能问题。我认为其中一个问题与mysql的配置以及它如何处理查询优化有关。
我无法完全理解为什么默认情况下不会使用以products_id和language_id作为主键的查询。这两个字段都是整数。
我们在mysql的配置中是否存在设置此行为的设置?
products_description | CREATE TABLE `products_description` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`language_id` int(11) NOT NULL DEFAULT '1',
`products_name` varchar(64) NOT NULL DEFAULT '',
`products_description` text,
`products_url` varchar(255) DEFAULT NULL,
`products_viewed` int(5) DEFAULT '0',
`products_name_sphinx` varchar(128) DEFAULT NULL,
PRIMARY KEY (`products_id`,`language_id`),
KEY `idx_products_name_zen` (`products_name`)
) ENGINE=MyISAM AUTO_INCREMENT=454992 DEFAULT CHARSET=latin1
这是一个在zen cart中运行的查询,在5.5.59上至少使用索引:
mysql> EXPLAIN SELECT `p`.`products_id` AS `id`, `pd`.`products_name` AS
`name` FROM `products` AS `p` LEFT JOIN `products_description` AS `pd` ON
`p`.`products_id`=`pd`.`products_id` WHERE `p`.`products_status`="1" AND `pd`.`language_id`="1"\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: p
type: ref
possible_keys: PRIMARY,idx_products_status_zen
key: idx_products_status_zen
key_len: 1
ref: const
rows: 108053
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: pd
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: p.products_id,const
rows: 1
Extra: Using where
2 rows in set (0.00 sec)
关于新的5.7.21
mysql> EXPLAIN SELECT `p`.`products_id` AS `id`, `pd`.`products_name` AS `name` FROM `products` AS `p` LEFT JOIN `products_description` AS `pd` ON `p`.`products_id`=`pd`.`products_id` WHERE `p`.`products_status`="1" AND `pd`.`language_id`="1"\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: pd
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 192860
filtered: 10.00
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: p
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,idx_products_status_zen
key: PRIMARY
key_len: 4
ref: pd.products_id
rows: 1
filtered: 55.95
Extra: Using where
2 rows in set, 1 warning (0.00 sec)
如果我将强制索引放入查询中:
mysql> EXPLAIN SELECT `p`.`products_id` AS `id`, `pd`.`products_name` AS `name` FROM `products` AS `p`, products_description `pd` force index (PRIMARY) WHERE p.products_id=pd.products_id and `p`.`products_status`=1 AND `pd`.`language_id`=1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: p
partitions: NULL
type: ref
possible_keys: PRIMARY,idx_products_status_zen
key: idx_products_status_zen
key_len: 1
ref: const
rows: 108024
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: pd
partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: p.products_id,const
rows: 1
filtered: 100.00
Extra: NULL
2 rows in set, 1 warning (0.00 sec)
EDIT: Here's the format=json explain:
EXPLAIN: {
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "86465.63"
},
"nested_loop": [
{
"table": {
"table_name": "pd",
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows_examined_per_scan": 192860,
"rows_produced_per_join": 19286,
"filtered": "10.00",
"cost_info": {
"read_cost": "59465.23",
"eval_cost": "3857.20",
"prefix_cost": "63322.43",
"data_read_per_join": "8M"
},
"used_columns": [
"products_id",
"language_id",
"products_name"
],
"attached_condition": "(`pd`.`language_id` = 1)"
}
},
{
"table": {
"table_name": "p",
"access_type": "eq_ref",
"possible_keys": [
"PRIMARY",
"idx_products_status_zen"
],
"key": "PRIMARY",
"used_key_parts": [
"products_id"
],
"key_length": "4",
"ref": [
"toolsource_zc.pd.products_id"
],
"rows_examined_per_scan": 1,
"rows_produced_per_join": 10791,
"filtered": "55.95",
"cost_info": {
"read_cost": "19286.00",
"eval_cost": "2158.22",
"prefix_cost": "86465.63",
"data_read_per_join": "4M"
},
"used_columns": [
"products_id",
"products_status"
],
"attached_condition": "(`p`.`products_status` = 1)"
}
}
]
}
}
1 row in set, 1 warning (0.00 sec)