4
explain SELECT * FROM pop_order_info poi  WHERE poi.is_delete = 0  and poi.vendor_id =7879  group by poi.order_sn limit 10;        
+----+-------------+-------+-------+----------------------------------------------------+------------------------------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys                                      | key                          | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+----------------------------------------------------+------------------------------+---------+------+--------+-------------+

|  1 | SIMPLE      | poi   | range | vendor_id_2,is_delete_vendor_id_order_sn,vendor_id | is_delete_vendor_id_order_sn | 5       | NULL | 158462 | Using where |
+----+-------------+-------+-------+----------------------------------------------------+------------------------------+---------+------+--------+-------------+
1 row in set (0.00 sec)

The above query is very slow! I created an index: is_delete_vendor_id_order_sn(is_delete,vendor_id,order_sn).

What does the 'type=range' mean in the above explain output?

Very fast by add hint:

explain SELECT * FROM pop_order_info poi use index(is_delete_vendor_id_order_sn) WHERE poi.is_delete = 0  and poi.vendor_id =7879  group by poi.order_sn limit 10;      
+----+-------------+-------+------+------------------------------+------------------------------+---------+-------------+--------+-------------+
| id | select_type | table | type | possible_keys                | key                          | key_len | ref         | rows   | Extra       |
+----+-------------+-------+------+------------------------------+------------------------------+---------+-------------+--------+-------------+

|  1 | SIMPLE      | poi   | ref  | is_delete_vendor_id_order_sn | is_delete_vendor_id_order_sn | 5       | const,const | 158462 | Using where |
+----+-------------+-------+------+------------------------------+------------------------------+---------+-------------+--------+-------------+
1 row in set (0.00 sec)
Shadow
  • 33,525
  • 10
  • 51
  • 64
Yafang Gao
  • 41
  • 1
  • 1
  • 3

2 Answers2

3

The type column of EXPLAIN output describes how tables are joined.

The following list describes the join types, ordered from the best type to the worst:

  • system
  • const
  • eq_ref
  • ref

All rows with matching index values are read from this table for each combination of rows from the previous tables. ref is used if the join uses only a leftmost prefix of the key or if the key is not a PRIMARY KEY or UNIQUE index (in other words, if the join cannot select a single row based on the key value). If the key that is used matches only a few rows, this is a good join type.

  • fulltext
  • ref_or_null
  • index_merge
  • unique_subquery
  • index_subquery
  • range

Only rows that are in a given range are retrieved, using an index to select the rows. The key column in the output row indicates which index is used. The key_len contains the longest key part that was used. The ref column is NULL for this type.

range can be used when a key column is compared to a constant using any of the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, or IN() operators:

If you are wonsering why join type , when retrieving from single table ,Read this

Read more here on EXPLAIN.

Community
  • 1
  • 1
Subin Chalil
  • 3,531
  • 2
  • 24
  • 38
  • 1
    I known the ordinary 'range' type operation.But in this SQL,I have two equal conditions,should be 'ref' (when I use hint,the execution plan ok) – Yafang Gao Nov 25 '15 at 12:53
1

There have been several bug fixes in this area in 5.6 and 5.7. Consider upgrading. However there are still open bugs in the general area.

A recent, not yet fixed, bug is optimizer prefers using index a to ORDER instead of b,a to EQ and ORDER.

You may want to create another bug with your case.

Rick James
  • 135,179
  • 13
  • 127
  • 222