Bug #12284 | Full index not used when joining tables | ||
---|---|---|---|
Submitted: | 30 Jul 2005 12:23 | Modified: | 18 Aug 2005 11:56 |
Reporter: | Perry Stupp | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 4.1.7 | OS: | Linux (Linux 2.4.7-10) |
Assigned to: | CPU Architecture: | Any |
[30 Jul 2005 12:23]
Perry Stupp
[30 Jul 2005 14:02]
Perry Stupp
Just wanted to add that when I do select * from datatable, fktable1, fktable2 where fktable1.name = 'one' and fktable2.name = 'two' and datatable.fk1 = fktable1.id and datatable.fk2 = fktable2.id and datetime = 'DATE1' it uses the full index and returns instantaneously. The problem of course is that I need a date range so this doesn't work for my application. I also found that the full index is used when the date range doesn't return any values.
[1 Aug 2005 22:56]
Perry Stupp
Perhaps this is better categorized under 'Optimizer'? Unfortunately my application won't scale without this capability and we have only a limited amount of time before we'll be forced back to Oracle if this isn't addressed. Any help would be greatly appreciated...
[2 Aug 2005 7:52]
Aleksey Kishkin
Hi! When I tested against 4.1.12 , I got little bit another query plan. Could you check your database against latest mysql server? And if you still have bad query plan, I need exact table definitions and data you tested (if it contains some private info, you can upload it to our ftp and nobody but developers will be able to read it). explain select * from datatable, fktable1, fktable2 where fktable1.name = 'A' and fktable2.name = 'B' and datatable.fk1 = fktable1.id and datatable.fk2 = fktable2.id and dt between '2005-01-01' and '2005-09-01'; +----+-------------+-----------+-------+---------------+---------+---------+-------------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------+-------+---------------+---------+---------+-------------+------+--------------------------+ | 1 | SIMPLE | fktable1 | const | PRIMARY,id | PRIMARY | 300 | const | 1 | | | 1 | SIMPLE | fktable2 | const | PRIMARY,id | PRIMARY | 300 | const | 1 | | | 1 | SIMPLE | datatable | ref | i1 | i1 | 24 | const,const | 1 | Using where; Using index | +----+-------------+-----------+-------+---------------+---------+---------+-------------+------+--------------------------+ 3 rows in set (0.00 sec) I did following tables: CREATE TABLE `datatable` ( `fk1` decimal(10,0) default NULL, `fk2` decimal(10,0) default NULL, `dt` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, KEY `i1` (`fk1`,`fk2`,`dt`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; CREATE TABLE `fktable1` ( `id` decimal(10,0) default NULL, `name` varchar(100) NOT NULL default '', PRIMARY KEY (`name`), UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; CREATE TABLE `fktable2` ( `id` decimal(10,0) default NULL, `name` varchar(100) NOT NULL default '', PRIMARY KEY (`name`), UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; insert into datatable values(1,2,NOW()); insert into datatable values(3,4,NOW()); insert into fktable1 values(1,'A'),(2,'B'),(3,'C'),(4,'D'),(5,'E'); insert into fktable2 values(1,'A'),(2,'B'),(3,'C'),(4,'D'),(5,'E');
[2 Aug 2005 13:04]
Perry Stupp
Aleksey, Thanks very much for your assistance. I have tried 4.1.13 and still have the same problem. I ran your test and it also worked as desired (Using Where; Using Index) so I suspect that this has something to do with the amount of data in the database. The database with Indexes is nearly 2GB (and growing) - assuming this is ok, please let me know how / where to upload it. Regards, Perry.
[2 Aug 2005 13:10]
Perry Stupp
If 2GB is too large, I can make the files available on our website for you to download. If that is preferred, let me know and I'll arrange a private login id for you.
[8 Aug 2005 6:55]
Aleksey Kishkin
I would prefer to write small script for populate tables with random values. When i have some results with this script I put them here.
[8 Aug 2005 17:26]
Perry Stupp
Aleksey, Thanks for your help. We have migrated the database to MS-SQL and the performance has improved substantially - I am lowering the severity of the ticket since I now have a workaround (albeit not the type of workaround that I had hoped for). We would still like to use MySQL so any on-going efforts to help address the problem won't be in vain. I'm wondering, we have quite a large index key cache set up for the database - is there any chance that this could be affecting the decision of the optimizer? It may be a bit of a stretch but perhaps it is choosing to read all of the extra rows of data to have the values cached for subsequent queries and since the value of the cache is so large it thinks that is what we want. I guess I can always try reducing the size of the cache to see what happens but I thought I'd throw that out there... Please let me know how you make out with your testing. Regards, Perry.
[18 Aug 2005 11:56]
Perry Stupp
Never mind, I managed to address the problem myself. Performance is back to where it should be and while not quite as good as SQL Server it is well beyond acceptable. Thanks anyway for what little help you tried to provide.
[5 Dec 2011 16:41]
Mark Summers
Perry, dare I ask what you did to work around this issue? I have observed it on a system with only 16M allocated to key_buffer. As far as I can tell, it is still not fixed, even in version 6 (supported by bug 19548). I have even encountered situations where highly useful compound indexes are entirely ignored in favor of less useful single-column indexes, and forcing the use of the compound index causes the query optimiser to down tools and refuse to use any index at all. I tried adjusting max_seeks_for_key in light of this but it made no difference. This issue is a real barrier to application scalability.