[MDEV-13347] MariaDB is not picking up encompassing index at all for ref query on TokuDB table Created: 2017-07-19  Updated: 2023-04-27

Status: Confirmed
Project: MariaDB Server
Component/s: Optimizer, Storage Engine - TokuDB
Affects Version/s: 5.5, 10.0, 10.1, 10.1.28, 10.2, 10.3
Fix Version/s: 10.4

Type: Bug Priority: Major
Reporter: Alex/AT Assignee: Sergei Petrunia
Resolution: Unresolved Votes: 0
Labels: None
Environment:

CentOS 7


Issue Links:
Duplicate
duplicates MDEV-6904 index_merge intersect(index_that_cove... Open
Relates
relates to MDEV-13372 Optimizer creates very bad execution ... Closed
relates to MDEV-13783 Index optimiser regression in 10.1.26... Open

 Description   

While table has an WHERE encompassing index (ref index), server is not picking it for update or select queries on large TokuDB table. This started from 10.1.24 and persists in 10.1.25-26.

SHOW CREATE TABLE `radacct`;

| radacct | CREATE TABLE `radacct` (
  `RadAcctId` bigint(21) NOT NULL AUTO_INCREMENT,
  `AcctSessionId` varchar(64) DEFAULT NULL,
  `AcctUniqueId` varchar(32) NOT NULL DEFAULT '',
  `UserName` varchar(64) NOT NULL DEFAULT '',
  `Realm` varchar(64) DEFAULT '',
  `NASIPAddress` varchar(15) NOT NULL DEFAULT '',
... other fields ...
  PRIMARY KEY (`RadAcctId`),
  KEY `UserName` (`UserName`),
  KEY `FramedIPAddress` (`FramedIPAddress`),
  KEY `AcctSessionId` (`AcctSessionId`),
  KEY `AcctUniqueId` (`AcctUniqueId`),
  KEY `AcctStartTime` (`AcctStartTime`),
  KEY `AcctStopTime` (`AcctStopTime`),
  KEY `NASIPAddress` (`NASIPAddress`),
  KEY `RadCheckProductID` (`ProductID`),
  KEY `AcctSessionId_UserName` (`AcctSessionId`,`UserName`),
  KEY `user_stop_start_ip` (`UserName`,`AcctStopTime`,`AcctStartTime`,`FramedIPAddress`),
  KEY `AcctStartTime_AcctUniqueId` (`AcctStartTime`,`AcctUniqueId`),
  KEY `CallingStationId` (`CallingStationId`),
  KEY `LastUpdated` (`LastUpdated`),
  KEY `AcctSessionId_2` (`AcctSessionId`,`UserName`,`NASIPAddress`),
 * KEY `updates` (`UserName`,`NASIPAddress`,`AcctSessionId`),*
  KEY `radacct` (`NASIPAddress`,`AcctSessionId`)
) ENGINE=TokuDB AUTO_INCREMENT=192662679 DEFAULT CHARSET=latin1 `compression`=tokudb_lzma |

Query:

UPDATE `radacct` SET `acctsessiontime` = 43570, `acctinputoctets` = 288561856, `acctinputoctets64` = 0<<32|288561856, `acctinputgigawords` = 0>>32, `acctoutputoctets` = 1946791036, `acctoutputoctets64` = 0<<32|1946791036, `acctoutputgigawords` = 0>>32, `framedipaddress` = '5.6.7.8', `lastupdated` = NOW() WHERE ((`UserName` = "username") AND (`NASIPAddress` = "1.2.3.4") AND (`AcctSessionId` = "ether 0/0/4:4096.224 0/0/0/0/0/0_00CE9067"));

Given the WHERE condition, it should pick up index 'updates' because it's encompassing (a full static ref), but it does not. What's worse, query behavior is seemingly random. It either picks single field index or uses index merge.

Explains:

| id   | select_type | table   | type        | possible_keys                                                                                                 | key                   | key_len | ref  | rows | filtered | Extra                                               |
|    1 | SIMPLE      | radacct | index_merge | UserName,AcctSessionId,NASIPAddress,AcctSessionId_UserName,user_stop_start_ip,AcctSessionId_2,updates,radacct | AcctSessionId,radacct | 67,84   | NULL |    1 |   100.00 | Using intersect(AcctSessionId,radacct); Using where |

Here it used intersect between AcctSessionId and the other index containing the other two fields.

| id   | select_type | table   | type  | possible_keys                                                                                                 | key           | key_len | ref  | rows | filtered | Extra       |
|    1 | SIMPLE      | radacct | range | UserName,AcctSessionId,NASIPAddress,AcctSessionId_UserName,user_stop_start_ip,AcctSessionId_2,updates,radacct | AcctSessionId | 67      | NULL |    1 |   100.00 | Using where |

And here it used just AcctSessionId index with a single field for the same query. Of course index can be unique for AcctSessionId, but query takes a whole lot of time showing 'Queried XXXXXX rows' where XXXXXX eventually goes to more than 30% of a table.

Sometimes it also uses UserName index.

*SHOW INDEX FROM `radacct`;*
 
| Table   | Non_unique | Key_name                   | Seq_in_index | Column_name      | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
| radacct |          0 | PRIMARY                    |            1 | RadAcctId        | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | UserName                   |            1 | UserName         | A         |       38674 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | FramedIPAddress            |            1 | FramedIPAddress  | A         |       57245 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | AcctSessionId              |            1 | AcctSessionId    | A         |    33259825 |     NULL | NULL   | YES  | BTREE      |         |               |
| radacct |          1 | AcctUniqueId               |            1 | AcctUniqueId     | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | AcctStartTime              |            1 | AcctStartTime    | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | AcctStopTime               |            1 | AcctStopTime     | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | NASIPAddress               |            1 | NASIPAddress     | A         |         467 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | RadCheckProductID          |            1 | ProductID        | A         |          61 |     NULL | NULL   | YES  | BTREE      |         |               |
| radacct |          1 | AcctSessionId_UserName     |            1 | AcctSessionId    | A         |    33259825 |     NULL | NULL   | YES  | BTREE      |         |               |
| radacct |          1 | AcctSessionId_UserName     |            2 | UserName         | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | user_stop_start_ip         |            1 | UserName         | A         |       49939 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | user_stop_start_ip         |            2 | AcctStopTime     | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | user_stop_start_ip         |            3 | AcctStartTime    | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | user_stop_start_ip         |            4 | FramedIPAddress  | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | AcctStartTime_AcctUniqueId |            1 | AcctStartTime    | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | AcctStartTime_AcctUniqueId |            2 | AcctUniqueId     | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | CallingStationId           |            1 | CallingStationId | A         |       79568 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | LastUpdated                |            1 | LastUpdated      | A         |     1446079 |     NULL | NULL   | YES  | BTREE      |         |               |
| radacct |          1 | AcctSessionId_2            |            1 | AcctSessionId    | A         |    33259825 |     NULL | NULL   | YES  | BTREE      |         |               |
| radacct |          1 | AcctSessionId_2            |            2 | UserName         | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | AcctSessionId_2            |            3 | NASIPAddress     | A         |    33259825 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | updates                    |            1 | UserName         | A         |       51645 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | updates                    |            2 | NASIPAddress     | A         |       83567 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | updates                    |            3 | AcctSessionId    | A         |    33259825 |     NULL | NULL   | YES  | BTREE      |         |               |
| radacct |          1 | radacct                    |            1 | NASIPAddress     | A         |         230 |     NULL | NULL   |      | BTREE      |         |               |
| radacct |          1 | radacct                    |            2 | AcctSessionId    | A         |    33259825 |     NULL | NULL   | YES  | BTREE      |         |               |

I have done recount rows ANALYZE and a full scale ANALYZE on the table (by allowing analyze to run for ages), it does not have any effect.



 Comments   
Comment by Elena Stepanova [ 2017-09-19 ]

Please provide the complete table definition without reductions. If they've been made for the sake of confidentiality, it doesn't make sense anyway, because the column names are still shown in indexes, we just lose information about their definition, and can't get the same plans as yours.

Did you try to use engine-independent table statistics? At least it should provide stable execution plans, whether they are going to be good plans remains to be seen.

Please also attach your cnf file(s).

Comment by Alex/AT [ 2017-09-19 ]

Hello Elena,

It was cut for shortness. Here is the complete current table definition (some index changes, but I still have to use FORCE INDEX for proper operation):

| radacct | CREATE TABLE `radacct` (
  `RadAcctId` bigint(21) NOT NULL AUTO_INCREMENT,
  `AcctSessionId` varchar(64) DEFAULT NULL,
  `AcctUniqueId` varchar(32) NOT NULL DEFAULT '',
  `UserName` varchar(64) NOT NULL DEFAULT '',
  `Realm` varchar(64) DEFAULT '',
  `NASIPAddress` varchar(15) NOT NULL DEFAULT '',
  `NASPort` int(12) DEFAULT NULL,
  `NASPortId` char(32) DEFAULT '0',
  `NASPortType` varchar(32) DEFAULT NULL,
  `AcctStartTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `AcctStopTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `AcctSessionTime` int(12) DEFAULT NULL,
  `AcctAuthentic` varchar(32) DEFAULT NULL,
  `ConnectInfo_start` varchar(32) DEFAULT NULL,
  `ConnectInfo_stop` varchar(32) DEFAULT NULL,
  `AcctInputOctets` bigint(12) DEFAULT NULL,
  `AcctOutputOctets` bigint(12) DEFAULT NULL,
  `CalledStationId` varchar(50) NOT NULL DEFAULT '',
  `CallingStationId` varchar(50) NOT NULL DEFAULT '',
  `AcctTerminateCause` varchar(32) NOT NULL DEFAULT '',
  `ServiceType` varchar(32) DEFAULT NULL,
  `FramedProtocol` varchar(32) DEFAULT NULL,
  `FramedIPAddress` varchar(15) NOT NULL DEFAULT '',
  `AcctStartDelay` int(12) DEFAULT NULL,
  `AcctStopDelay` int(12) DEFAULT NULL,
  `ProductID` bigint(20) DEFAULT NULL,
  `AcctInputGigawords` int(11) DEFAULT '0',
  `AcctOutputGigawords` int(11) DEFAULT '0',
  `AcctInputOctets64` char(18) DEFAULT '0',
  `AcctOutputOctets64` char(18) DEFAULT '0',
  `LastUpdated` datetime DEFAULT NULL,
  PRIMARY KEY (`RadAcctId`),
  KEY `UserName` (`UserName`),
  KEY `AcctSessionId` (`AcctSessionId`),
  KEY `AcctUniqueId` (`AcctUniqueId`),
  KEY `AcctStartTime` (`AcctStartTime`),
  KEY `AcctStopTime` (`AcctStopTime`),
  KEY `RadCheckProductID` (`ProductID`),
  KEY `user_start_stop_ip` (`UserName`,`AcctStartTime`,`AcctStopTime`,`FramedIPAddress`),
  KEY `user_stop` (`UserName`,`AcctStopTime`),
  KEY `user_stop_start_ip` (`UserName`,`AcctStopTime`,`AcctStartTime`,`FramedIPAddress`),
  KEY `AcctStartTime_AcctUniqueId` (`AcctStartTime`,`AcctUniqueId`),
  KEY `CallingStationId` (`CallingStationId`),
  KEY `LastUpdated` (`LastUpdated`),
  KEY `updates` (`UserName`,`NASIPAddress`,`AcctSessionId`),
  KEY `NASIPAddress` (`NASIPAddress`),
  KEY `stale` (`AcctStopTime`,`LastUpdated`),
  KEY `FramedIPAddress` (`FramedIPAddress`)
) ENGINE=TokuDB AUTO_INCREMENT=194622508 DEFAULT CHARSET=latin1 `compression`='tokudb_zlib' 

Comment by Alex/AT [ 2017-09-19 ]

For engine-independent table statistics, I assume we have not used it, we have use_stat_tables = NEVER in variable list. I'll read on the matter and try it. Doing full scan to ANALYZE from time to time may be bad though, the table is huge.

Comment by Alex/AT [ 2017-09-19 ]

Configuration is as follows:

[mysqld]
datadir=/db/mysql
port=3306
socket=/var/lib/mysql/mysql.sock
pid-file=/var/lib/mysql/mysql.pid
default-storage-engine=InnoDB
user=mysql
open_files_limit=8192
innodb_file_per_table
skip-name-resolve
 
# charset
character-sets-dir=/usr/share/mysql/charsets
character-set-server=utf8
 
# fix for .NET appservers with pooling issues
connect_timeout=300
 
# This one does not affect the issue, I've tried commenting it already
optimizer_switch=index_merge_sort_union=on,index_merge_sort_intersection=on,orderby_uses_equalities=on
 
# optimization
table_cache=1024
max_connections=1024
back_log=1024
thread_cache_size=4
concurrent_insert=2
delay_key_write=ALL
max_allowed_packet=16M
preload_buffer_size=256K
key_buffer_size=16M
join_buffer_size=16M
query_cache_size=128M
query_cache_limit=256K
query_prealloc_size=64K
transaction_prealloc_size=64K
sort_buffer_size=16M
read_buffer_size=64K
read_rnd_buffer_size=64K
tmp_table_size=64K
max_heap_table_size=32M
innodb_file_format=Barracuda
innodb_buffer_pool_size=320M
innodb_log_buffer_size=32M
innodb_log_file_size=64M
 
# recovery
innodb_force_recovery = 0
myisam-recover=DEFAULT,BACKUP,FORCE
 
# logs
log-error = /db/logs/mysql.log
slow_query_log = 1
slow_query_log_file = /db/logs/mysql-slow.log
 
# binlog
binlog_format=MIXED
log-bin=/db/binlog/mysql_binary_log
log-slave-updates=1
binlog-do-db=radius
binlog-do-db=dns
binlog-do-db=maildb
binlog-do-db=mail
binlog-do-db=ACS
binlog-do-db=webconfig_snappy
binlog-do-db=ldap
binlog-do-db=managed_cpes
server-id=1
gtid-domain-id=40
expire_logs_days=666
 
# temp dir
tmpdir=/db/temp
 
[mysqld_safe]
log-error = /db/logs/mysqld-safe.log
 
[mariadb]
plugin-load=ha_tokudb
tokudb_cache_size=320M
tokudb_data_dir=/db/tokudb/data
tokudb_log_dir=/db/tokudb/log
tokudb_tmp_dir=/db/tokudb/temp
tokudb_lock_timeout=50000
tokudb_prelock_empty=0
 
[client]
character-sets-dir=/usr/share/mysql/charsets
socket=/var/lib/mysql/mysql.sock

Comment by Elena Stepanova [ 2017-09-19 ]

Thanks.

Doing full scan to ANALYZE from time to time may be bad though, the table is huge.

This is very true, and also it can take quite a lot of resources, which is why I don't usually suggest it for really big tables. However, if you have a staging instance, it would be worth trying to see if it really helps, and if it does, what's the price for it (analyze time).

Comment by Phil Sweeney [ 2017-10-01 ]

I am having similar issues since 10.1.24. elenst has linked TDB-2 to this, but I don't think it is related unless you have wrong row counts (do check this though!).

The regression occurs immediately on upgrading to 10.1.24 and can be fixed immediately by downgrading to 10.1.23 on the same data dir. The other way to (temporarily, I think) work around is by doing ALTER TABLE blah ENGINE=tokudb; and for some reason after doing this the index selection is correct. Obviously this is a very expensive operation for large tables.

Comment by Alex/AT [ 2017-10-01 ]

Thanks for the info, Phil. Row counts are correct. Indeed the table it's not picking up index for has hot created indexes (including the one it's not picking up), so it may really be related to TDB-35.

Comment by Phil Sweeney [ 2017-10-01 ]

OK!! Now you've have got me thinking about this again and after re-reading Jun's fix for TDB-35, I've realised that each index has its own row count, and this wasn't being written to the metadata properly. So I remembered from an old row count ticket there's a CLI utility to dump the tokudb info.

I've had a look at one of the indexes that is being inappropriately used and I see this:

$ /usr/local/mysql/bin/tokuftdump --header /var/lib/mysql/data/forum/<table>key<index_name>_190f8b66d_3_1d_P_0.tokudb
<snip>
estimated numrows=2412860
estimated numbytes=260980666
logical row count=-8978474

Yeah.. negative 9 million rows for logical row count.

I had a look at the slave where i did the alter table engine=tokudb and low and behold (of course):

estimated numrows=2395122
estimated numbytes=260981897
logical row count=2411520

Can you try this command and see what yours looks like Alex/AT? Next step of course is how can we repair this row count without doing an alter table engine=tokudb. I guess you can hot create another index (with the fix for TDB-35) and drop the original. And using this CLI command you can determine which indexes are broken across your tables.

Comment by Alex/AT [ 2017-10-01 ]

Indeed I have some broken counts, but they're just -1, not a large negative value.

_radius_sql_5600_2b_key_AcctStopTime_a6_8_1b.tokudb
estimated numrows=28729817
logical row count=-1
_radius_sql_5600_2b_key_AcctUniqueId_a6_6_1b.tokudb
estimated numrows=7046798
logical row count=-1
_radius_sql_5600_2b_key_RadCheckProductID_a6_a_1b.tokudb
estimated numrows=9840951
logical row count=-1

I'm now trying to roll up my own RPMs of 10.1.28 with the patch included. It will take some time because I need to stage-test it.

Comment by Phil Sweeney [ 2017-10-01 ]

OK I compiled my own build of 10.1.28 with the two line fix for TDB-35. Can confirm that creating a new hot index for the index with the wrong logical row count (checked via the CLI utility).. and dropping the old one corrects the index selection. Now to find all my indexes with the wrong row count :-/

Comment by Alex/AT [ 2017-10-01 ]

Okay, I've build 10.1.28 with patch/commit fixing TDB-35 (https://github.com/percona/PerconaFT/commit/9783d7a6b5ba3a623f6d7b3afe98f9bac06d6038) applied, and it passed all the internal tests. I've rolled it up on the server in question and was trying to recover from a wrong query plan condition by recreating indexes.

I'll put conclusion first to clarify things: nor TDB-2, nor TDB-35 fixes solve this wrong query plan issue. It's still using an index merge instead of encompassing index. I tried EXPAIN at different moments (after first index rebuild / see below, after second index rebuild and after doing full background ANALYZE on a table). All of them displayed the same query plan using index merge.

And now for the good/bad news after trying 10.1.28 with TDB-35 fix:

1. /good/ Row counts on index recreation seemingly return back to normal. I don't have any '-1' count shown by tokuftdump --header anymore.

2. /bad/ Update from 10.1.25 to 10.1.28 broke total row counts for the table again, and then when recreating indexes I've got 'fetched XXXXXX rows out of 0 rows', 'fetched XXXXXX rows out of 35 rows' and other stuff like that. Resulting index cardinality on recreation was affected by that and was seemingly wrong.

3. /good/ After doing ANALYZE in RECOUNT ROWS mode, total row count returned to normal, allowing me to recreate indexes properly.

4. /bad/ After recreating indexes, I've got strangely similar cardinality values for all the indexes after recreating them. Wonder if that is as it should be...
---------------------------------------------------------------------------------------------------------------------------------------------

Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment

---------------------------------------------------------------------------------------------------------------------------------------------

radacct 0 PRIMARY 1 RadAcctId A 6558353 NULL NULL   BTREE    
radacct 1 UserName 1 UserName A 6558353 NULL NULL   BTREE    
radacct 1 FramedIPAddress 1 FramedIPAddress A 6558353 NULL NULL   BTREE    
radacct 1 NASIPAddress 1 NASIPAddress A 6558353 NULL NULL   BTREE    
radacct 1 AcctUniqueId 1 AcctUniqueId A 6558353 NULL NULL   BTREE    
radacct 1 AcctSessionId 1 AcctSessionId A 6558353 NULL NULL YES BTREE    
radacct 1 AcctStartTime 1 AcctStartTime A 6558353 NULL NULL   BTREE    
radacct 1 AcctStopTime 1 AcctStopTime A 6558353 NULL NULL   BTREE    
radacct 1 CallingStationId 1 CallingStationId A 6558353 NULL NULL   BTREE    
radacct 1 RadCheckProductID 1 ProductID A 6558353 NULL NULL YES BTREE    
radacct 1 LastUpdated 1 LastUpdated A 6558353 NULL NULL YES BTREE    
radacct 1 AcctStartTime_AcctUniqueId 1 AcctStartTime A 6558353 NULL NULL   BTREE    
radacct 1 AcctStartTime_AcctUniqueId 2 AcctUniqueId A 6558353 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 1 UserName A 6558353 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 2 AcctStartTime A 6558353 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 3 AcctStopTime A 6558353 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 4 FramedIPAddress A 6558353 NULL NULL   BTREE    
radacct 1 user_stop 1 UserName A 6558353 NULL NULL   BTREE    
radacct 1 user_stop 2 AcctStopTime A 6558353 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 1 UserName A 6558353 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 2 AcctStopTime A 6558353 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 3 AcctStartTime A 6558353 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 4 FramedIPAddress A 6558353 NULL NULL   BTREE    
radacct 1 updates 1 UserName A 6558353 NULL NULL   BTREE    
radacct 1 updates 2 NASIPAddress A 6558353 NULL NULL   BTREE    
radacct 1 updates 3 AcctSessionId A 6558353 NULL NULL YES BTREE    
radacct 1 stale 1 AcctStopTime A 6558353 NULL NULL   BTREE    
radacct 1 stale 2 LastUpdated A 6558353 NULL NULL YES BTREE    

---------------------------------------------------------------------------------------------------------------------------------------------

5. /bad/ Full background ANALYZE did not return cardinality to adequate until restarting the mariadb server process.
Seems like we have some another bug here: background ANALYZE does not post cardinality changes to the engine.

Comment by Alex/AT [ 2017-10-01 ]

Indeed I can confirm another (but unrelated) problem with background ANALYZE. Foreground one pushes cardinalities back properly. Should I create a separate bug ticket for that?

Comment by Alex/AT [ 2017-10-01 ]

So for this one, where are we now:
1. 10.1.28 with TDB-35 fix applied.
2. Cardinalities are seemingly ok (given ANALYZE was run as foreground), row counts are ok.
3. Query plan still wrong. I assume it has to do something with optimizer, not only TokuDB.

Comment by Phil Sweeney [ 2017-10-01 ]

alex/at My master DB is now running with my custom build, and I only fixed the index with -9,000,000 rows. The rest are all either normal values or -1. I have a feeling -1 is OK and probably means logical row counts are ignored. Everything seems to be running OK for me right now.

You seem to have an unrelated issue to the logical_row_count on the index.

Comment by Alex/AT [ 2017-10-01 ]

Indeed, this seems to be a combination of issues. Fixing logical row counts fixed some other queries plans but this one still remains
Hopefully someone from MariaDB team can shed a light on that.

But another thing is: backup server running on 10.1.23 do not exhibit this behavior So regression is still somewhere around 10.1.24.

Comment by Phil Sweeney [ 2017-10-01 ]

alex/at So with my main issue fixed (The minus 8 million row index).. I'm now seeing a small number of queries that are doing crazy stuff and scanning millions of rows - guess I'm seeing similar things to you now. Time to return to 10.1.23 :-/

Comment by Elena Stepanova [ 2017-10-02 ]

Elena Stepanova has linked TDB-2 to this, but I don't think it is related

philsweeney, I intentionally link them all together. It doesn't imply direct causation, but I think this cluster of problems should be looked at as a whole, otherwise it is likely to cause even more confusion – when one tries fix A, and it doesn't help, then one instead tries fix B, it also doesn't help, while in fact it only helps when you apply A, and B, and also some C on top of it (but without A and B there will be no effect of C). We do need to look into the suspected optimizer problem, but we can only do it efficiently if there are no obvious upstream problems on the way.

So for this one, where are we now:
1. 10.1.28 with TDB-35 fix applied.
2. Cardinalities are seemingly ok (given ANALYZE was run as foreground), row counts are ok.
3. Query plan still wrong. I assume it has to do something with optimizer, not only TokuDB.

Alex/AT, could you please provide the summary of this variation of the problem (or point at parts of it if they are already here among all the comments):

  • show create table if it's different from the description
  • row counts (statistics from I_S)
  • cardinalities (SHOW INDEX IN or alike)
  • query
  • execution plan (if possible, in the form of ANALYZE FORMAT=JSON <query> – but be aware that it will actually execute the DML, so if it's undesirable or too time-consuming, then the traditional one)
  • expected execution plan (if you can tweak it with hints) or just verbose description of your expectation
Comment by Alex/AT [ 2017-10-02 ]

Sure thing. I'll do in in multiple posts.

Table definition (no, it does not really differ):

| radacct | CREATE TABLE `radacct` (
  `RadAcctId` bigint(21) NOT NULL AUTO_INCREMENT,
  `AcctSessionId` varchar(64) DEFAULT NULL,
  `AcctUniqueId` varchar(32) NOT NULL DEFAULT '',
  `UserName` varchar(64) NOT NULL DEFAULT '',
  `Realm` varchar(64) DEFAULT '',
  `NASIPAddress` varchar(15) NOT NULL DEFAULT '',
  `NASPort` int(12) DEFAULT NULL,
  `NASPortId` char(32) DEFAULT '0',
  `NASPortType` varchar(32) DEFAULT NULL,
  `AcctStartTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `AcctStopTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `AcctSessionTime` int(12) DEFAULT NULL,
  `AcctAuthentic` varchar(32) DEFAULT NULL,
  `ConnectInfo_start` varchar(32) DEFAULT NULL,
  `ConnectInfo_stop` varchar(32) DEFAULT NULL,
  `AcctInputOctets` bigint(12) DEFAULT NULL,
  `AcctOutputOctets` bigint(12) DEFAULT NULL,
  `CalledStationId` varchar(50) NOT NULL DEFAULT '',
  `CallingStationId` varchar(50) NOT NULL DEFAULT '',
  `AcctTerminateCause` varchar(32) NOT NULL DEFAULT '',
  `ServiceType` varchar(32) DEFAULT NULL,
  `FramedProtocol` varchar(32) DEFAULT NULL,
  `FramedIPAddress` varchar(15) NOT NULL DEFAULT '',
  `AcctStartDelay` int(12) DEFAULT NULL,
  `AcctStopDelay` int(12) DEFAULT NULL,
  `ProductID` bigint(20) DEFAULT NULL,
  `AcctInputGigawords` int(11) DEFAULT '0',
  `AcctOutputGigawords` int(11) DEFAULT '0',
  `AcctInputOctets64` char(18) DEFAULT '0',
  `AcctOutputOctets64` char(18) DEFAULT '0',
  `LastUpdated` datetime DEFAULT NULL,
  PRIMARY KEY (`RadAcctId`),
  KEY `UserName` (`UserName`),
  KEY `FramedIPAddress` (`FramedIPAddress`),
  KEY `AcctUniqueId` (`AcctUniqueId`),
  KEY `AcctSessionId` (`AcctSessionId`),
  KEY `AcctStartTime` (`AcctStartTime`),
  KEY `AcctStopTime` (`AcctStopTime`),
  KEY `CallingStationId` (`CallingStationId`),
  KEY `RadCheckProductID` (`ProductID`),
  KEY `LastUpdated` (`LastUpdated`),
  KEY `AcctStartTime_AcctUniqueId` (`AcctStartTime`,`AcctUniqueId`),
  KEY `user_start_stop_ip` (`UserName`,`AcctStartTime`,`AcctStopTime`,`FramedIPAddress`),
  KEY `user_stop` (`UserName`,`AcctStopTime`),
  KEY `user_stop_start_ip` (`UserName`,`AcctStopTime`,`AcctStartTime`,`FramedIPAddress`),
  KEY `updates` (`UserName`,`NASIPAddress`,`AcctSessionId`),
  KEY `stale` (`AcctStopTime`,`LastUpdated`),
  KEY `NASIPAddress` (`NASIPAddress`)
) ENGINE=TokuDB AUTO_INCREMENT=194947711 DEFAULT CHARSET=latin1 `compression`='tokudb_zlib'

Comment by Alex/AT [ 2017-10-02 ]

INFORMATION_SCHEMA data:

TABLES

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
def radius radacct BASE TABLE TokuDB 10 Dynamic 6552800 372 2441337995 9223372036854775807 3667676735 18446744069536708694 194947741 2015-09-28 10:40:15 2017-10-02 06:42:51 NULL latin1_swedish_ci NULL `compression`='tokudb_zlib'  

TokuDB_fractal_tree_info

dictionary_name internal_file_name bt_num_blocks_allocated bt_num_blocks_in_use bt_size_allocated bt_size_in_use table_schema table_name table_dictionary_name
./radius/radacct-key-AcctSessionId /db/tokudb/data/_radius_radacct_key_AcctSessionId_17a69764_3_1d_B_0.tokudb 121 121 62528000 50169417 radius radacct key-AcctSessionId
./radius/radacct-key-AcctStartTime /db/tokudb/data/_radius_radacct_key_AcctStartTime_17a6c223_3_1d_B_0.tokudb 55 55 36520960 35826750 radius radacct key-AcctStartTime
./radius/radacct-key-AcctStartTime_AcctUniqueId /db/tokudb/data/_radius_radacct_key_AcctStartTime_AcctUniqueId_17a7495b_3_1d_B_0.tokudb 107 107 157975552 156575828 radius radacct key-AcctStartTime_AcctUniqueId
./radius/radacct-key-AcctStopTime /db/tokudb/data/_radius_radacct_key_AcctStopTime_17a6d286_3_1d_B_0.tokudb 110 56 41564160 39984702 radius radacct key-AcctStopTime
./radius/radacct-key-AcctUniqueId /db/tokudb/data/_radius_radacct_key_AcctUniqueId_17a66ccc_3_1d_B_0.tokudb 92 92 153154048 128172101 radius radacct key-AcctUniqueId
./radius/radacct-key-CallingStationId /db/tokudb/data/_radius_radacct_key_CallingStationId_17a6f7af_3_1d_B_0.tokudb 104 104 40336896 34341445 radius radacct key-CallingStationId
./radius/radacct-key-FramedIPAddress /db/tokudb/data/_radius_radacct_key_FramedIPAddress_17a641c2_3_1d_B_0.tokudb 63 63 33589248 27132997 radius radacct key-FramedIPAddress
./radius/radacct-key-LastUpdated /db/tokudb/data/_radius_radacct_key_LastUpdated_17a73c94_3_1d_B_0.tokudb 94 48 31870976 29947458 radius radacct key-LastUpdated
./radius/radacct-key-NASIPAddress /db/tokudb/data/_radius_radacct_key_NASIPAddress_17a87ba5_3_1d_B_0.tokudb 134 68 28427264 27357765 radius radacct key-NASIPAddress
./radius/radacct-key-RadCheckProductID /db/tokudb/data/_radius_radacct_key_RadCheckProductID_17a722d1_3_1d_B_0.tokudb 41 41 25395712 23821890 radius radacct key-RadCheckProductID
./radius/radacct-key-UserName /db/tokudb/data/_radius_radacct_key_UserName_17a633bb_3_1d_B_0.tokudb 74 74 36732928 29462597 radius radacct key-UserName
./radius/radacct-key-stale /db/tokudb/data/_radius_radacct_key_stale_17a80a12_3_1d_B_0.tokudb 124 63 45487104 43228753 radius radacct key-stale
./radius/radacct-key-updates /db/tokudb/data/_radius_radacct_key_updates_17a7e586_3_1d_B_0.tokudb 184 184 65729536 55432821 radius radacct key-updates
./radius/radacct-key-user_start_stop_ip /db/tokudb/data/_radius_radacct_key_user_start_stop_ip_17a76c0c_3_1d_B_0.tokudb 128 128 97480192 81173625 radius radacct key-user_start_stop_ip
./radius/radacct-key-user_stop /db/tokudb/data/_radius_radacct_key_user_stop_17a78a50_3_1d_B_0.tokudb 89 89 66537472 54097492 radius radacct key-user_stop
./radius/radacct-key-user_stop_start_ip /db/tokudb/data/_radius_radacct_key_user_stop_start_ip_17a7b0ce_3_1d_B_0.tokudb 128 128 100743680 86226041 radius radacct key-user_stop_start_ip
./radius/radacct-main /db/tokudb/data/_radius_sql_5600_2b_main_a6_2_1b.tokudb 3674 1590 689671168 615507994 radius radacct main
./radius/radacct-status /db/tokudb/data/_radius_sql_5600_2b_status_a6_1_1b.tokudb 11 9 41472 4096 radius radacct status
Comment by Alex/AT [ 2017-10-02 ]

SHOW INDEX output: please note row count already differs a bit: the table is very active on writes (append mostly, major deletes sometimes)

Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
radacct 0 PRIMARY 1 RadAcctId A 6552804 NULL NULL   BTREE    
radacct 1 UserName 1 UserName A 47484 NULL NULL   BTREE    
radacct 1 FramedIPAddress 1 FramedIPAddress A 47830 NULL NULL   BTREE    
radacct 1 AcctUniqueId 1 AcctUniqueId A 6552804 NULL NULL   BTREE    
radacct 1 AcctSessionId 1 AcctSessionId A 6552804 NULL NULL YES BTREE    
radacct 1 AcctStartTime 1 AcctStartTime A 6552804 NULL NULL   BTREE    
radacct 1 AcctStopTime 1 AcctStopTime A 6552804 NULL NULL   BTREE    
radacct 1 CallingStationId 1 CallingStationId A 50406 NULL NULL   BTREE    
radacct 1 RadCheckProductID 1 ProductID A 1 NULL NULL YES BTREE    
radacct 1 LastUpdated 1 LastUpdated A 6552804 NULL NULL YES BTREE    
radacct 1 AcctStartTime_AcctUniqueId 1 AcctStartTime A 6552804 NULL NULL   BTREE    
radacct 1 AcctStartTime_AcctUniqueId 2 AcctUniqueId A 6552804 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 1 UserName A 47484 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 2 AcctStartTime A 6552804 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 3 AcctStopTime A 6552804 NULL NULL   BTREE    
radacct 1 user_start_stop_ip 4 FramedIPAddress A 6552804 NULL NULL   BTREE    
radacct 1 user_stop 1 UserName A 47484 NULL NULL   BTREE    
radacct 1 user_stop 2 AcctStopTime A 6552804 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 1 UserName A 47484 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 2 AcctStopTime A 6552804 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 3 AcctStartTime A 6552804 NULL NULL   BTREE    
radacct 1 user_stop_start_ip 4 FramedIPAddress A 6552804 NULL NULL   BTREE    
radacct 1 updates 1 UserName A 47484 NULL NULL   BTREE    
radacct 1 updates 2 NASIPAddress A 48182 NULL NULL   BTREE    
radacct 1 updates 3 AcctSessionId A 6552804 NULL NULL YES BTREE    
radacct 1 stale 1 AcctStopTime A 6552804 NULL NULL   BTREE    
radacct 1 stale 2 LastUpdated A 6552804 NULL NULL YES BTREE    
radacct 1 NASIPAddress 1 NASIPAddress A 25 NULL NULL   BTREE    
Comment by Alex/AT [ 2017-10-02 ]

The query is:

analyze format=json  UPDATE `radacct`         SET           `acctsessiontime` = 10853,           `acctinputoctets` = 9394240,           `acctinputoctets64` = 0<<32|9394240,           `acctinputgigawords` = 0>>32,           `acctoutputoctets` = 385664891,           `acctoutputoctets64` = 0<<32|385664891,           `acctoutputgigawords` = 0>>32,           `framedipaddress` = '<IP>',           `lastupdated` = NOW()         WHERE           (`acctsessionid` = '<long string>') AND (`username` = '<small string>') AND (`nasipaddress` = '<IP>');

Some values were hidden as <...> because of being user-specific information, but they does not matter. There is multitude of such queries and the worst thing query plan seemingly varies as random for them even for a single query.

Comment by Alex/AT [ 2017-10-02 ]

ANALYZE with a seemingly weird query plan (now it uses intersect with unnecessary secondary index given 100% encompassed match):

{
  "query_block": {
    "select_id": 1,
    "r_total_time_ms": 0.509,
    "table": {
      "update": 1,
      "table_name": "radacct",
      "access_type": "index_merge",
      "possible_keys": [
        "UserName",
        "AcctSessionId",
        "user_start_stop_ip",
        "user_stop",
        "user_stop_start_ip",
        "updates",
        "NASIPAddress"
      ],
      "index_merge": {
        "intersect": {
          "range": {
            "key": "AcctSessionId",
            "used_key_parts": ["AcctSessionId"]
          },
          "range": {
            "key": "updates",
            "used_key_parts": ["UserName", "NASIPAddress", "AcctSessionId"]
          }
        }
      },
      "rows": 1,
      "r_rows": 1,
      "r_filtered": 100,
      "r_total_time_ms": 0.2273,
      "attached_condition": "((radacct.AcctSessionId = '<long string>') and (radacct.UserName = '<small string>') and (radacct.NASIPAddress = '<IP>'))"
    }
  }
}

For now it just intersects with AcctSessionId, that's ok and fast. But when it starts intersecting with i.e. UserName or NASIPAddress, things start looking grim: full scan for each update.

Even just using AcctSessionId without any intersection would be much better because it's almost unique. But this is still wrong nevertheless. Also, it strangely tries to intersect key with another key fully containing that first one key.

And as said (well, better to repeat myself here): query plans are random. Once it's AcctSessionId, it's ok. But when it's suddenly some other index... well, it starts crawling: doing 50-100 full scans per second is tad too much.

Comment by Alex/AT [ 2017-10-02 ]

Expected query plan: I've added FORCE INDEX (`updates`) to force the proper index:

{
  "query_block": {
    "select_id": 1,
    "r_total_time_ms": 0.3426,
    "table": {
      "update": 1,
      "table_name": "radacct",
      "access_type": "range",
      "possible_keys": ["updates"],
      "key": "updates",
      "key_length": "150",
      "used_key_parts": ["UserName", "NASIPAddress", "AcctSessionId"],
      "rows": 1,
      "r_rows": 1,
      "r_filtered": 100,
      "r_total_time_ms": 0.2908,
      "attached_condition": "((radacct.AcctSessionId = '<long string>') and (radacct.UserName = '<small string>') and (radacct.NASIPAddress = '<IP>'))"
    }
  }
}

This results in much simpler plan. Shouldn't it be ref type query? The key is not unique, but nevertheless it's full ref.

Comment by Alex/AT [ 2017-10-02 ]

The least possible repeatable case I found is:

CREATE TABLE `radacct_test` (
  `RadAcctId` bigint(21) NOT NULL AUTO_INCREMENT,
  `AcctSessionId` varchar(64) DEFAULT NULL,
  `AcctUniqueId` varchar(32) NOT NULL DEFAULT '',
  `UserName` varchar(64) NOT NULL DEFAULT '',
  `Realm` varchar(64) DEFAULT '',
  `NASIPAddress` varchar(15) NOT NULL DEFAULT '',
  `NASPort` int(12) DEFAULT NULL,
  `NASPortId` char(32) DEFAULT '0',
  `NASPortType` varchar(32) DEFAULT NULL,
  `AcctStartTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `AcctStopTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `AcctSessionTime` int(12) DEFAULT NULL,
  `AcctAuthentic` varchar(32) DEFAULT NULL,
  `ConnectInfo_start` varchar(32) DEFAULT NULL,
  `ConnectInfo_stop` varchar(32) DEFAULT NULL,
  `AcctInputOctets` bigint(12) DEFAULT NULL,
  `AcctOutputOctets` bigint(12) DEFAULT NULL,
  `CalledStationId` varchar(50) NOT NULL DEFAULT '',
  `CallingStationId` varchar(50) NOT NULL DEFAULT '',
  `AcctTerminateCause` varchar(32) NOT NULL DEFAULT '',
  `ServiceType` varchar(32) DEFAULT NULL,
  `FramedProtocol` varchar(32) DEFAULT NULL,
  `FramedIPAddress` varchar(15) NOT NULL DEFAULT '',
  `AcctStartDelay` int(12) DEFAULT NULL,
  `AcctStopDelay` int(12) DEFAULT NULL,
  `ProductID` bigint(20) DEFAULT NULL,
  `AcctInputGigawords` int(11) DEFAULT '0',
  `AcctOutputGigawords` int(11) DEFAULT '0',
  `AcctInputOctets64` char(18) DEFAULT '0',
  `AcctOutputOctets64` char(18) DEFAULT '0',
  `LastUpdated` datetime DEFAULT NULL,
  PRIMARY KEY (`RadAcctId`),
  KEY `UserName` (`UserName`),
  KEY `FramedIPAddress` (`FramedIPAddress`),
  KEY `AcctUniqueId` (`AcctUniqueId`),
  KEY `AcctSessionId` (`AcctSessionId`),
  KEY `AcctStartTime` (`AcctStartTime`),
  KEY `AcctStopTime` (`AcctStopTime`),
  KEY `CallingStationId` (`CallingStationId`),
  KEY `RadCheckProductID` (`ProductID`),
  KEY `LastUpdated` (`LastUpdated`),
  KEY `AcctStartTime_AcctUniqueId` (`AcctStartTime`,`AcctUniqueId`),
  KEY `user_start_stop_ip` (`UserName`,`AcctStartTime`,`AcctStopTime`,`FramedIPAddress`),
  KEY `user_stop` (`UserName`,`AcctStopTime`),
  KEY `user_stop_start_ip` (`UserName`,`AcctStopTime`,`AcctStartTime`,`FramedIPAddress`),
  KEY `updates` (`UserName`,`NASIPAddress`,`AcctSessionId`),
  KEY `stale` (`AcctStopTime`,`LastUpdated`),
  KEY `NASIPAddress` (`NASIPAddress`)
) ENGINE=TokuDB DEFAULT CHARSET=latin1 `compression`='tokudb_zlib';

INSERT INTO `radacct_test` (`AcctSessionId`, `username`, `nasipaddress`) VALUES ('a', 'b', 'c'), ('d', 'e', 'c');

ANALYZE FORMAT=json UPDATE `radacct_test` SET `acctsessiontime` = 10990, `acctinputoctets` = 339842, `acctinputoctets64` = 0<<32|339842,
	`acctinputgigawords` = 0>>32, `acctoutputoctets` = 269650, `acctoutputoctets64` = 0<<32|269650, `acctoutputgigawords` = 0>>32,
        `framedipaddress` = '1.2.3.4', `lastupdated` = NOW()
	WHERE (`acctsessionid` = 'd') AND (`username` = 'e') AND (`nasipaddress` = 'c');

ANALYZE FORMAT=json UPDATE `radacct_test` FORCE INDEX (`updates`) SET `acctsessiontime` = 10990, `acctinputoctets` = 339842, `acctinputoctets64` = 0<<32|339842,
	`acctinputgigawords` = 0>>32, `acctoutputoctets` = 269650, `acctoutputoctets64` = 0<<32|269650, `acctoutputgigawords` = 0>>32,
        `framedipaddress` = '1.2.3.4', `lastupdated` = NOW()
	WHERE (`acctsessionid` = 'd') AND (`username` = 'e') AND (`nasipaddress` = 'c');

The query without FORCE INDEX uses intersect on `UserName` and `NASIPAddress` or `AcctSessionId` instead of ref to `updates`, and that's totally bad in case of huge table...

{
  "query_block": {
    "select_id": 1,
    "r_total_time_ms": 0.3586,
    "table": {
      "update": 1,
      "table_name": "radacct_test",
      "access_type": "index_merge",
      "possible_keys": [
        "UserName",
        "AcctSessionId",
        "user_start_stop_ip",
        "user_stop",
        "user_stop_start_ip",
        "updates",
        "NASIPAddress"
      ],
      "index_merge": {
        "intersect": {
          "range": {
            "key": "UserName",
            "used_key_parts": ["UserName"]
          },
          "range": {
            "key": "AcctSessionId",
            "used_key_parts": ["AcctSessionId"]
          }
        }
      },
      "rows": 1,
      "r_rows": 1,
      "r_filtered": 100,
      "r_total_time_ms": 0.1465,
      "attached_condition": "((radacct_test.AcctSessionId = 'd') and (radacct_test.UserName = 'e') and (radacct_test.NASIPAddress = 'c'))"
    }
  }
}

Comment by Phil Sweeney [ 2017-10-24 ]

alex/at Maybe try that reproducer on Percona Server, then if it happens there too, log the issue in Percona's jira.

Comment by Alex/AT [ 2017-11-15 ]

This requires me to build a completely separate test environment, but indeed I'll do.

Comment by Phil Sweeney [ 2017-11-17 ]

alex/at Just FYI the reproducer seems to happen on 10.1.23 as well - which seems to contradict the idea it was introduced in 10.1.24.

Comment by Phil Sweeney [ 2017-11-18 ]

Alex/AT Also FYI I randomly stumbled upon this old ticket that looks similar: https://jira.mariadb.org/browse/MDEV-6904

Comment by Alice Sherepa [ 2018-01-16 ]

Phil Sweeney, Alex/AT, thanks a lot.
It looks like it is the same bug as MDEV-6904, reproducible with TokuDB and InnoDB, not with myisam on MariaDB 5.5-10.3

a little bit simplified testcase:

CREATE TABLE t1 (
  acc varchar(64) DEFAULT NULL, nm varchar(64), a1 varchar(15), u datetime DEFAULT NULL,
  KEY (nm),
  KEY (acc),
  KEY ind3 (nm,a1,acc),
  KEY (a1)) ENGINE=TokuDB ;
 
INSERT INTO t1 (acc, nm, a1) VALUES ('a', 'b', 'c'), ('d', 'e', 'c');
 
EXPLAIN UPDATE t1  SET  u = NOW() WHERE (acc = 'd') AND (nm = 'e') AND (a1 = 'c');
EXPLAIN UPDATE t1 FORCE INDEX (ind3) SET  u = NOW() WHERE (acc = 'd') AND (nm = 'e') AND (a1 = 'c');

--------------
EXPLAIN UPDATE t1  SET  u = NOW() WHERE (acc = 'd') AND (nm = 'e') AND (a1 = 'c')
--------------
+------+-------------+-------+-------------+----------------+--------+---------+------+------+--------------------------------------+
| id   | select_type | table | type        | possible_keys  | key    | key_len | ref  | rows | Extra                                |
+------+-------------+-------+-------------+----------------+--------+---------+------+------+--------------------------------------+
|    1 | SIMPLE      | t1    | index_merge | nm,acc,ind3,a1 | nm,acc | 67,67   | NULL |    1 | Using intersect(nm,acc); Using where |
+------+-------------+-------+-------------+----------------+--------+---------+------+------+--------------------------------------+
1 row in set (0.00 sec)
 
--------------
EXPLAIN UPDATE t1 FORCE INDEX (ind3) SET  u = NOW() WHERE (acc = 'd') AND (nm = 'e') AND (a1 = 'c')
--------------
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | t1    | range | ind3          | ind3 | 152     | NULL |    1 | Using where |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
 
--------------
ANALYZE FORMAT=json UPDATE t1  SET  u = NOW() WHERE (acc = 'd') AND (nm = 'e') AND (a1 = 'c')
--------------
{
  "query_block": {
    "select_id": 1,
    "r_total_time_ms": 0.3286,
    "table": {
      "update": 1,
      "table_name": "t1",
      "access_type": "index_merge",
      "possible_keys": ["nm", "acc", "ind3", "a1"],
      "index_merge": {
        "intersect": {
          "range": {
            "key": "nm",
            "used_key_parts": ["nm"]
          },
          "range": {
            "key": "acc",
            "used_key_parts": ["acc"]
          }
        }
      },
      "rows": 1,
      "r_rows": 1,
      "r_filtered": 100,
      "r_total_time_ms": 0.0657,
      "attached_condition": "((t1.acc = 'd') and (t1.nm = 'e') and (t1.a1 = 'c'))"
    }
  }
} 
1 row in set (0.07 sec)
 
--------------
ANALYZE FORMAT=json UPDATE t1 FORCE INDEX (ind3) SET  u = NOW() WHERE (acc = 'd') AND (nm = 'e') AND (a1 = 'c')
--------------
{
  "query_block": {
    "select_id": 1,
    "r_total_time_ms": 0.0577,
    "table": {
      "update": 1,
      "table_name": "t1",
      "access_type": "range",
      "possible_keys": ["ind3"],
      "key": "ind3",
      "key_length": "152",
      "used_key_parts": ["nm", "a1", "acc"],
      "rows": 1,
      "r_rows": 1,
      "r_filtered": 100,
      "r_total_time_ms": 0.0266,
      "attached_condition": "((t1.acc = 'd') and (t1.nm = 'e') and (t1.a1 = 'c'))"
    }
  }
} 
1 row in set (0.00 sec)

Comment by Alex/AT [ 2018-06-05 ]

Bump. Still relevant.

Generated at Thu Feb 08 08:04:53 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.