| Bug #70086 | Degraded performance for index_merge updates | ||
|---|---|---|---|
| Submitted: | 19 Aug 2013 16:06 | Modified: | 2 Nov 2013 8:52 |
| Reporter: | trevor price | Email Updates: | |
| Status: | No Feedback | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
| Version: | 5.6.13-log | OS: | Linux (2.6.16.33-xenU x86_64) |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | index_merge update performance | ||
[19 Aug 2013 16:17]
trevor price
Some additional information.
1) According the show status "Handler" variables, the update and select behave the same, so its seems the optimizer is not the problem.
2) Using the performance schema, the update spends nearly all its time "fetching".
*************************** 4. row ***************************
event_id: 17572601
rows_examined: 4
event_name: stage/sql/updating
event_name: wait/io/table/sql/handler
operation: fetch
sum(waitl.timer_wait): 19953568
not sure if row locking happens during this operation, but perhaps the query is slower because of row-locking overhead.
[19 Aug 2013 16:34]
trevor price
so, dropping of of the indicies being merged greatly speeds performance
mysql> explain update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: power_up_value
type: range
possible_keys: track_id_idx
key: track_id_idx
key_len: 8
ref: const
rows: 949
Extra: Using where
1 row in set (0.00 sec)
mysql> update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
the station_id_ix index was dropped, which was part of the index_merge.
[20 Aug 2013 21:19]
Sveta Smirnova
Thank you for the report. I can not repeat described behavior with test data. Did you try to run ANALYZE TABLE and OPTIMIZE TABLE on problematic table?
[20 Aug 2013 22:06]
trevor price
yes I ran optimize table and analyze table. This is a single table query, so I can upload the entire table, it's around 600MB.
[20 Aug 2013 23:22]
trevor price
Here is a more concise rendering of the problem.
----------------------
mysql> optimize table power_up_value ;
+----------------------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------------------+----------+----------+-------------------------------------------------------------------+
| jelli.power_up_value | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| jelli.power_up_value | optimize | status | OK |
+----------------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (1 min 31.39 sec)
mysql> analyze table power_up_value ;
+----------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+----------------------+---------+----------+----------+
| jelli.power_up_value | analyze | status | OK |
+----------------------+---------+----------+----------+
1 row in set (0.01 sec)
mysql> alter table power_up_value add index station_id_idx (station_id) ;
Query OK, 0 rows affected (14.42 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: power_up_value
type: index_merge
possible_keys: track_id_idx,station_id_idx
key: track_id_idx,station_id_idx
key_len: 8,8
ref: NULL
rows: 72
Extra: Using intersect(track_id_idx,station_id_idx); Using where
1 row in set (0.00 sec)
mysql> update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
Query OK, 1 row affected (0.37 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
Query OK, 0 rows affected (0.35 sec)
Rows matched: 1 Changed: 0 Warnings: 0
mysql> alter table power_up_value drop index station_id_idx ;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> explain update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: power_up_value
type: range
possible_keys: track_id_idx
key: track_id_idx
key_len: 8
ref: const
rows: 961
Extra: Using where
1 row in set (0.00 sec)
mysql> update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
------------------------
[5 Sep 2013 9:05]
Jørgen Løland
Hi Trevor, If you can upload a repeatable test case from your data it would come very handy for us. If you're able to reduce the test case down a bit from 600MB it would be even better - most likely you don't need all the columns and rows to make a test case. I'll investigate the reason once I get a repro. Thanks, Jørgen
[6 Sep 2013 15:48]
trevor price
a data file has been ftp'd to ftp.oracle.com. This file is bug-data-70086.zip, and the instructions to replicate the issue are in the README.
[1 Oct 2013 11:02]
Jørgen Løland
Hi Trevor, Due to unexpected issues, your uploaded repro has been deleted from the ftp server. I would really like to take a look at the repro, but I'm afraid I didn't get hold of it while it was available. Can you please upload it one more time? We're terribly sorry for the inconvenience. Regards, Jørgen
[3 Nov 2013 1:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".

Description: Between 5.5.8 and 5.6.13 the performance for some update statements has gotten significantly worse. Consider the statement mysql> explain update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: power_up_value type: index_merge possible_keys: track_id_idx,station_id_idx key: track_id_idx,station_id_idx key_len: 8,8 ref: NULL rows: 69 Extra: Using intersect(track_id_idx,station_id_idx); Using where on the table mysql> show create table jelli.power_up_value \G *************************** 1. row *************************** Table: power_up_value Create Table: CREATE TABLE `power_up_value` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `track_id` bigint(20) unsigned NOT NULL, `station_id` bigint(20) unsigned NOT NULL, `power_up_id` bigint(20) unsigned DEFAULT NULL, `active` bit(1) NOT NULL, `value` bigint(20) NOT NULL, `applied_server_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `inactivated_server_time` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `FK_power_up_value_to_power_up` (`power_up_id`), KEY `track_id_idx` (`track_id`), KEY `station_id_idx` (`station_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3177130 DEFAULT CHARSET=utf8 for the data set in question on 5.6.13 this statement takes : mysql> update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 ; Query OK, 0 rows affected (0.23 sec) so .23 seconds. On mysql 5.5.8 on the same data it takes ~ .04 seconds. This is a huge difference. Notice the 0 rows were modified. Now look at the time if I convert this update statement into a select mysql> select sql_no_cache * from jelli.power_up_value where active<>0 and track_id=76821 and station_id=3519 \G *************************** 1. row *************************** id: 3177012 track_id: 76821 station_id: 3519 power_up_id: 13032192 active: value: 0 applied_server_time: 2013-08-17 00:52:58 inactivated_server_time: NULL 1 row in set (0.04 sec) It does not seem correct to me that a zero row modified update statement will take 5X the equivalent statement as a select. This is a show stopping performance issue for us since it slows replication. How to repeat: CREATE TABLE `power_up` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `user_id` bigint(20) unsigned NOT NULL, `track_id` bigint(20) unsigned DEFAULT NULL COMMENT 'track_id == null means not yet applied', `station_id` bigint(20) unsigned DEFAULT NULL, `active` bit(4) NOT NULL COMMENT 'Use to inactivate a power up - for auditing reasons, do not delete power ups from the database!', `type` varchar(20) NOT NULL, `last_modified_server_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `apply_time` timestamp NULL DEFAULT NULL, `expiration_time` timestamp NULL DEFAULT NULL, `version` int(10) unsigned NOT NULL DEFAULT '1', `apply_client_id` int(5) DEFAULT NULL, `in_orbit` enum('0','1') DEFAULT '0', PRIMARY KEY (`id`), KEY `FK_vote_to_user` (`user_id`), KEY `FK_vote_to_track` (`track_id`), KEY `FK_power_up_to_station` (`station_id`), KEY `last_modified_server_time_idx` (`last_modified_server_time`), KEY `expiration_time_idx` (`expiration_time`), KEY `in_orbit_idx` (`station_id`,`in_orbit`), KEY `apply_time_idx` (`apply_time`) ) ENGINE=InnoDB with update update jelli.power_up_value set value=0 where active<>0 and track_id=76821 and station_id=3519 ;