简体   繁体   中英

Mysql performance tuning

I'm trying to figure out how i can improve the performance of this query and i believe it may be my indexes; some of my thoughts are that date may be causing the poor performance or that i have the indexs in the order wrong. Also are there any other suggestions anyone has on how to improve the speed that are not index related? Thanks, i look forward to any input!

Here's what I've tried so far

 ALTER TABLE data ADD INDEX(data_timestamp, first,last);
 ALTER table data add index(first);
 ALTER table data add index(first);
 ALTER TABLE data add index (data_timestamp);

The following query(the second one) below runs a subquery for each row of a database in order to get the previous average at the instant of each point

select count(*) from data where data_timestamp like '2015-01-01%'; -> 362855

select (select sum(first*last) / sum(last)
FROM data t2
WHERE data_timestamp like '2015-12-18%'
AND t2.data_timestamp <= t1.data_timestamp
), t1.*
FROM data t1
WHERE data_timestamp like '2015-12-18%';

For optimum performance, you want an index range scan operation for the data_timestamp column. The predicate in the query of the form:

  WHERE data_timestamp LIKE '2015-12-18%' 

is forcing MySQL to evaluate EVERY value of data_timestamp in the table, effectively converting the datetime/timestamp value into a string, and then performing a string comparison on the converted value.

If we use a predicate with a comparison to datetime values, then MySQL can make more effective use of an index that has data_timestamp as a leading column. For example:

  WHERE data_timestamp >= '2015-12-18'
    AND data_timestamp <  '2015-12-18' + INTERVAL 1 DAY

The EXPLAIN output for a query using the LIKE pattern will show

type
------
index

That shows the query can make use of an index. But it's doing a full scan of the index, looking at every row in the index. But a much more efficient pattern is available. We can allow MySQL to quickly eliminate vast swaths of rows in the index from being considered, by using a range scan operation. A query with a predicate as in the second example will (should) show:

type
------
range

That's going to improve performance for a query that is pulling a relatively small number of rows from a large set.


More explanation, in case I didn't make this clear. Writing:

  WHERE ts_col LIKE '2015-12-18%' 

is effectively the same as writing

  WHERE CONVERT(ts_col,CHAR(18)) LIKE '2015-12-18%' 

And that forces MySQL to perform the CONVERT operation on the value in the ts_col for every row in the table.

BOTTOM LINE

Don't force unnecessary datatype conversions of columns from the table. Instead, compare columns to their native datatypes.

You can do an "explain" query to the database to figure out what is happening. Just write "explain" before any query.

Is not necessary to add indexes for first and last. You're only searching in data_timestamp fields so that's the only one index you need.

On the other hand, you might be having problems regarding to using "like %" in date columns. Check if there are another alternatives to do the same. If data_timestamp is a text column, you should add a full text index to the field. If data_timestamp is a date column, use "between" instead "like". "explain" tells you which index is used by the query.

For this query you need only ALTER TABLE tic_data add index (data_timestamp) . But data_timestamp must be of CHAR or VARCHAR type (you scan it with LIKE <string%> ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM