Home  >  Article  >  Database  >  Detailed explanation of index and FROM_UNIXTIME issues in mysql

Detailed explanation of index and FROM_UNIXTIME issues in mysql

小云云
小云云Original
2018-01-17 10:45:081829browse

This article mainly introduces the relevant information on the index and FROM_UNIXTIME issues in mysql. Friends who need it can refer to it. I hope it can help everyone.

Zero, background

After simply collecting some information, I found that this slow query problem is deeply hidden. After asking many people, including the DBA, I still don’t know the reason.

1. Problem

There is a DB with a field defined as follows.


MySQL [d_union_stat]> desc t_local_cache_log_meta;
+----------------+--------------+------+-----+---------------------+
| Field     | Type     | Null | Key | Default       |
+----------------+--------------+------+-----+---------------------+
| c_id      | int(11)   | NO  | PRI | NULL        |
| c_key     | varchar(128) | NO  | MUL |           |
| c_time     | int(11)   | NO  | MUL | 0          |
| c_mtime    | varchar(45) | NO  | MUL | 0000-00-00 00:00:00 |
+----------------+--------------+------+-----+---------------------+
17 rows in set (0.01 sec)

The index is as follows:


MySQL [d_union_stat]> show index from t_local_cache_log_meta \G     
*************************** 1. row ***************************
    Table: t_local_cache_log_meta
  Non_unique: 0
   Key_name: PRIMARY
 Column_name: c_id
  Collation: A
 Cardinality: 6517096
  Index_type: BTREE
*************************** 2. row ***************************
.
.
.
*************************** 6. row ***************************
    Table: t_local_cache_log_meta
  Non_unique: 1
   Key_name: index_mtime
 Column_name: c_mtime
  Collation: A
 Cardinality: 592463
  Index_type: BTREE
6 rows in set (0.02 sec)

Then I wrote a SQL as follows:


SELECT 
  count(*)
FROM
  d_union_stat.t_local_cache_log_meta
where
  `c_mtime` < FROM_UNIXTIME(1494485402);

Finally one day the DBA came over and gave me a report, saying that this SQL was slow SQL.


# Time: 170518 11:31:14
# Query_time: 12.312329 Lock_time: 0.000061 Rows_sent: 0 Rows_examined: 5809647
SET timestamp=1495078274;
DELETE FROM `t_local_cache_log_meta` WHERE `c_mtime`< FROM_UNIXTIME(1494473461) limit 1000;

I was speechless. My DB is indexed and SQL is carefully optimized. Why is SQL slow?

When asked why it is slow SQL, the DBA couldn’t answer it. Even the colleagues around me couldn’t answer it.

I secretly thought that I had encountered a deeply hidden knowledge point.

There are two suspicious places: 1. There are 6 indexes. 2. The rvalue is the FROM_UNIXTIME function.

So I checked the official MYSQL documentation and found that 6 were not problems.

All storage engines support at least 16 indexes per table and a total index length of at least 256 bytes.
Most storage engines have higher limits.

So I suspect the problem is FROM_UNIXTIME function.

Then look at the INDEX section of MYSQL and find some clues.

1.To find the rows matching a WHERE clause quickly.
2. To eliminate rows from consideration.
If there is a choice between multiple indexes, MySQL normally uses the index that finds the smallest number of rows.
3.If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to look up rows.
4. MySQL can use indexes on columns more efficiently if they are declared as the same type and size.
Comparison of dissimilar columns (comparing a string column to a temporal or numeric column, for example) may prevent use of indexes if values ​​cannot be compared directly without conversion.

When I saw Article 4, it was mentioned that different types may lead to no indexing. Could it be that the return value of FROM_UNIXTIME cannot be converted into a string type?

So query the return value of the FROM_UNIXTIME function.

MySQL FROM_UNIXTIME() returns a date /datetime from a version of unix_timestamp.

The return is a time type, which is forced to be converted to a string type Woolen cloth?


MySQL [d_union_stat]> explain SELECT 
  ->   *
  -> FROM
  ->   t_local_cache_log_meta
  -> where
  ->   `c_mtime` = CONCAT(FROM_UNIXTIME(1494485402)) \G
*************************** 1. row ***************************
      id: 1
 select_type: SIMPLE
    table: t_local_cache_log_meta
     type: ref
possible_keys: index_mtime
     key: index_mtime
   key_len: 137
     ref: const
     rows: 1
    Extra: Using where
1 row in set (0.01 sec)

This time you can see that the index is used and only one piece of data is scanned.

2. Conclusion

This time, you can use the index by forcing the return value of FROM_UNIXTIME to be converted.

So this SQL cannot use the upper index because the types of rvalues ​​and lvalues ​​are inconsistent. .

Related recommendations:

How to create an index for a join table related to two tables in MySQL Detailed graphic and text explanation

MySQL partition field Is it necessary to create a separate index for the column?

Introduction to the method of viewing, creating and deleting indexes in MySQL

The above is the detailed content of Detailed explanation of index and FROM_UNIXTIME issues in mysql. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn