Bug #2022 | Query Optimizer occaisionally uses wrong plan on the same query | ||
---|---|---|---|
Submitted: | 5 Dec 2003 9:00 | Modified: | 10 Dec 2003 18:26 |
Reporter: | David Chazin | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server | Severity: | S2 (Serious) |
Version: | 4.0.11 gamma | OS: | Windows (Windows 2000) |
Assigned to: | Igor Babaev | CPU Architecture: | Any |
[5 Dec 2003 9:00]
David Chazin
[5 Dec 2003 10:17]
Dean Ellis
There have been optimizer changes/bugfixes since 4.0.11 (which is from February). Would you be able to test this against a current release and see if the problem persists?
[5 Dec 2003 11:59]
David Chazin
I tested it with 4.1.1-alpha and it has the same behavior.
[5 Dec 2003 14:30]
Dean Ellis
Verified in 4.0.17/Linux. Populated peptide_trypsin with 16 million rows, with unique peptide_id (same value for molecular weight). Populated pep_to_prot with 32 million rows, two rows for each peptide_id. Other columns were populated with random data. mysql> explain select pep_to_prot.protein_id from peptide_trypsin, pep_to_prot where molecular_weight between 1 and 500 and peptide_trypsin.peptide_id = pep_to_prot.peptide_id; +-----------------+-------+-------------------+----------+---------+----------------------------+--------+-------------+ | table | type | possible_keys | key | key_len | ref | rows | Extra | +-----------------+-------+-------------------+----------+---------+----------------------------+--------+-------------+ | peptide_trypsin | range | id_index,mw_index | mw_index | 4 | NULL | 484 | Using where | | pep_to_prot | ref | PRIMARY | PRIMARY | 4 | peptide_trypsin.peptide_id | 259999 | Using index | +-----------------+-------+-------------------+----------+---------+----------------------------+--------+-------------+ 2 rows in set (0.00 sec) mysql> explain select pep_to_prot.protein_id from peptide_trypsin, pep_to_prot where molecular_weight between 1 and 600 and peptide_trypsin.peptide_id = pep_to_prot.peptide_id; +-----------------+-------+-------------------+----------+---------+------------------------+----------+-------------+ | table | type | possible_keys | key | key_len | ref | rows | Extra | +-----------------+-------+-------------------+----------+---------+------------------------+----------+-------------+ | pep_to_prot | index | PRIMARY | PRIMARY | 8 | NULL | 25999998 | Using index | | peptide_trypsin | ref | id_index,mw_index | id_index | 4 | pep_to_prot.peptide_id | 1 | Using where | +-----------------+-------+-------------------+----------+---------+------------------------+----------+-------------+ 2 rows in set (0.00 sec) With my particular set of data, the behavior changes at: molecular_weight between 1 and 553. Thank you.
[10 Dec 2003 18:26]
Igor Babaev
It's not a bug. After rinning the analyze command collecting statistics on the index of the table pep_to_prot we have: mysql> explain -> select pep_to_prot.protein_id from peptide_trypsin, pep_to_prot -> where molecular_weight between 1 and 500 and -> peptide_trypsin.peptide_id = pep_to_prot.peptide_id; +----+-------------+-----------------+-------+-------------------+----------+---------+---------------------------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+-------+-------------------+----------+---------+---------------------------------+------+-------------+ | 1 | SIMPLE | peptide_trypsin | range | id_index,mw_index | mw_index | 4 | NULL | 496 | Using where | | 1 | SIMPLE | pep_to_prot | ref | PRIMARY | PRIMARY | 4 | test.peptide_trypsin.peptide_id | 2 | Using index | +----+-------------+-----------------+-------+-------------------+----------+---------+---------------------------------+------+-------------+ 2 rows in set (4.71 sec) and mysql> explain -> select pep_to_prot.protein_id from peptide_trypsin, pep_to_prot -> where molecular_weight between 1 and 600 and -> peptide_trypsin.peptide_id = pep_to_prot.peptide_id; +----+-------------+-----------------+-------+-------------------+----------+---------+---------------------------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+-------+-------------------+----------+---------+---------------------------------+------+-------------+ | 1 | SIMPLE | peptide_trypsin | range | id_index,mw_index | mw_index | 4 | NULL | 595 | Using where | | 1 | SIMPLE | pep_to_prot | ref | PRIMARY | PRIMARY | 4 | test.peptide_trypsin.peptide_id | 2 | Using index | +----+-------------+-----------------+-------+-------------------+----------+---------+---------------------------------+------+-------------+ 2 rows in set (0.06 sec) Please, always run the analyze command when you have strange execution plans for queries, especially for those executing against big tables.