查询优化器中的更改从mysql 5.5.59更改为5.7.21

时间:2018-03-09 13:27:39

标签: mysql

我们已经升级了数据库硬件,并从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)

0 个答案:

没有答案