mysql> SELECT SQL_NO_CACHE COUNT(rb.subscription_id) as recurring_cc_count,
-> SUM(rb.grace_price) as recurring_cc, -> COUNT(sb.subscription_id) as single_cc_count, -> SUM(sb.initial_amt) as single_cc -> FROM customerdetail a -> LEFT JOIN recurringbilling rb -> ON a.subscription_id = rb.subscription_id -> LEFT JOIN singlebilling sb -> ON a.subscription_id = sb.subscription_id -> LEFT JOIN (global.subscriptionExchangeRate as ser INNER JOIN global.currencyCodes as cur) -> ON (a.subscription_id = ser.subscriptionId AND ser.billedCurrencyCode = cur.currencyCode) -> WHERE client_accnum = '12345' -> AND a.trans_timestamp -> BETWEEN '20070108000000' AND '20070108235959'; +--------------------+--------------+-----------------+-----------+ | recurring_cc_count | recurring_cc | single_cc_count | single_cc | +--------------------+--------------+-----------------+-----------+ | 4 | 119.80 | 0 | NULL | +--------------------+--------------+-----------------+-----------+ 1 row in set (0.40 sec) mysql> explain SELECT SQL_NO_CACHE COUNT(rb.subscription_id) as recurring_cc_count, -> SUM(rb.grace_price) as recurring_cc, -> COUNT(sb.subscription_id) as single_cc_count, -> SUM(sb.initial_amt) as single_cc -> FROM customerdetail a -> LEFT JOIN recurringbilling rb -> ON a.subscription_id = rb.subscription_id -> LEFT JOIN singlebilling sb -> ON a.subscription_id = sb.subscription_id -> LEFT JOIN (global.subscriptionExchangeRate as ser INNER JOIN global.currencyCodes as cur) -> ON (a.subscription_id = ser.subscriptionId AND ser.billedCurrencyCode = cur.currencyCode) -> WHERE client_accnum = '12345' -> AND a.trans_timestamp -> BETWEEN '20070108000000' AND '20070108235959'; +----+-------------+-------+--------+----------------------------------- -----------------------------+-----------------+---------+-------------- -----------------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+----------------------------------- -----------------------------+-----------------+---------+-------------- -----------------+------+--------------------------+ | 1 | SIMPLE | a | range | client_idx,trans_idx,accno_trans_idx,accnumactive,accsubactive | accno_trans_idx | 7 | NULL | 4 | Using where; Using index | | 1 | SIMPLE | rb | eq_ref | PRIMARY | PRIMARY | 8 | company.a.subscription_id | 1 | | | 1 | SIMPLE | sb | eq_ref | PRIMARY | PRIMARY | 8 | company.a.subscription_id | 1 | | | 1 | SIMPLE | ser | ref | PRIMARY,billedCurrencyCode | PRIMARY | 8 | company.a.subscription_id | 1 | | | 1 | SIMPLE | cur | eq_ref | PRIMARY | PRIMARY | 2 | global.ser.billedCurrencyCode | 1 | Using index | +----+-------------+-------+--------+----------------------------------- -----------------------------+-----------------+---------+-------------- -----------------+------+--------------------------+ 5 rows in set (0.00 sec) mysql> show index from customerdetail; +----------------+------------+-----------------+--------------+-------- ---------+-----------+-------------+----------+--------+------+--------- ---+--------- + | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +----------------+------------+-----------------+--------------+-------- ---------+-----------+-------------+----------+--------+------+--------- ---+--------- ..........................SNIP........................................ | customerdetail | 1 | accno_trans_idx | 1 | client_accnum | A | 17052 | NULL | NULL | | BTREE | | | customerdetail | 1 | accno_trans_idx | 2 | trans_timestamp | A | 49042196 | NULL | NULL | | BTREE | ..........................SNIP........................................ +----------------+------------+-----------------+--------------+-------- ---------+-----------+-------------+----------+--------+------+--------- ---+---------+ The query executes orders of magnitude faster, and the EXPLAIN shows why. MySQL has now chosen to use the accno_trans_idx index for the customerdetail table which has much better cardinality (almost 1 key per row). The obvious workaround is use FORCE INDEX(accno_trans_idx) in the query for now, but I'm beginning to think this may be a bug. Has anyone else had any similar issues? I haven't found anything like this in the bug database though. If anyone doesn't see anything blatantly wrong with my setup, I'll submit this as a bug. Further information: Here is how MySQL is configured, and the my.cnf I'm using. CC="gcc -m64" CXX="g++ -m64" \ ./configure --prefix=/usr \ --sbindir=/usr/sbin \ --libexecdir=/usr/sbin \ --infodir=/usr/share/man \ --mandir=/usr/share/info \ --libdir=/usr/lib64 \ --enable-shared \ --enable-static \ --enable-thread-safe-client \ --enable-local-infile \ --with-extra-charsets=all \ --with-gnu-ld \ --with-pthread \ --with-unix-socket-path=/tmp/mysql.sock \ --with-mysqld-user=mysql \ --without-debug \ --with-openssl=/usr \ --with-big-tables \ --with-archive-storage-engine \ --with-csv-storage-engine \ --with-blackhole-storage-engine \ --with-federated-storage-engine \ --with-berkeley-db \ --with-berkeley-includes=/usr/include \ --with-berkeley-libs=/usr/lib64 \ --without-extra-tools \ --with-mysqlmanager=no \ --with-ndbcluster \ --without-geometry ---------------------- [mysqld] #Directories datadir=/var/db/mysql socket=/tmp/mysql.sock log-error=/var/log/mysql/mysql.log pid-file=/var/run/mysqld/mysqld.pid tmpdir=/tmp #Replication server-id=127 #log-bin= replicate-ignore-db=mysql #log-slave-updates #Network max_connections=1024 max_allowed_packet=1024M net_buffer_length=16k #Files open_files_limit=8192 # Anything higher needs corresponding ulimit entry #Buffers join_buffer_size=128M key_buffer_size=512M key_buffer=512M large_pages max_heap_table_size=1024M myisam_sort_buffer_size=256M read_buffer_size=64M read_buffer=64M query_cache_size=32M query_cache_type=1 record_buffer=512 sort_buffer=512M table_cache=512 thread_cache=4M thread_stack=512K thread_cache_size=300 thread_concurrency=16 tmp_table_size=1G #innodb innodb-table-locks=off transaction_isolation=REPEATABLE-READ innodb_buffer_pool_size=1024M innodb_log_buffer_size=8M innodb_flush_log_at_trx_commit=0 innodb_log_file_size=128M innodb_additional_mem_pool_size=32M innodb_thread_concurrency=16 innodb_commit_concurrency=4 innodb_flush_method=O_DIRECT innodb_open_files=8192 innodb_sync_spin_loops=32 innodb_thread_sleep_delay=1000 innodb_autoextend_increment=1024M innodb_file_per_table=TRUE [client] socket=/tmp/mysql.sock John Anderson