Home > Database > Mysql Tutorial > Detailed explanation of index and FROM_UNIXTIME problems in mysql

Detailed explanation of index and FROM_UNIXTIME problems in mysql

黄舟
Release: 2017-05-28 09:53:40
Original
1581 people have browsed it

This article mainly introduces the relevant information about index and FROM_UNIXTIME in mysql. Friends who need it can refer to

Zero, background

I received a lot of alarms this Thursday. I checked with the DBA and found a slow query.

After simply collecting some information, I found that this slow query problem is deeply hidden. Many people including the DBA did not know the reason after asking.

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)
Copy after login

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)
Copy after login

Then I wrote a SQL as follows:

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

Finally one day the DBA came over and gave me a running message, 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;
Copy after login

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 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 that the problem is the 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 the string type?

So query the return value of FROM_UNIXTIME function.

MySQL FROM_UNIXTIME() <a href="http://www.php.cn/wiki/135.html" target="_blank">return</a>s a <a href="http://www.php.cn/wiki/1255.html" target="_blank">date</a> /datetime from a version of unix_timestamp.

returned It is a time type, what about forcing it to be converted to a string type?

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)
Copy after login

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. .

Okay, let’s not say more. This article is just an interlude. Let’s continue to introduce the algorithm later.

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

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template