任何想法为什么cli.clitype和c.cli没有被选中,即使我在/ sql中使用/ force index作为提示。它仅在下面的查询中以4秒为单位提供输出以获取1634。我正在使用5.5.25.log请建议。
mysql> explain SELECT DATE(sr.`date`), v.company_name, c.cli, COUNT(*), c.charge, SUM(c.`charge`) FROM subscriptionrequest AS sr, cli AS c , vendor AS v WHERE sr.cli = c.cli AND sr.secretkey = v.secretkey AND sr.`date` BETWEEN'2012-03-12 00:00:00' AND '2012-10-13 00:00:00' and c.clitype = 'chargemo' GROUP BY DATE(sr.`date`), sr.secretkey,c.cli;
+----+-------------+-------+------+-----------------------------------------------+----------------+---------+----------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------------------------------------+----------------+---------+----------------------------+------+----------------------------------------------+
| 1 | SIMPLE | c | ALL | idx_cli | NULL | NULL | NULL | 115 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | sr | ref | idx_subreq_key,idx_subreq_cli,idx_subreq_date | idx_subreq_cli | 53 | crystal_du_sm.c.cli | 869 | Using where |
| 1 | SIMPLE | v | ref | secretkey_idx | secretkey_idx | 52 | crystal_du_sm.sr.secretkey | 1 | Using where |
+----+-------------+-------+------+-----------------------------------------------+----------------+---------+----------------------------+------+----------------------------------------------+
3 rows in set (0.00 sec)
mysql> show indexes from cli;
+-------+------------+--------------+--------------+-------------+-----------+--------- ----+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------+--------------+-------------+-----------+-------- -----+----------+--------+------+------------+---------+---------------+
| cli | 0 | PRIMARY | 1 | idcli | A | 115 | NULL | NULL | | BTREE | | |
| cli | 1 | idx_cli | 1 | cli | A | 115 | NULL | NULL | | BTREE | | |
| cli | 1 | cli_type_idx | 1 | clitype | A | 115 | NULL | NULL | YES | BTREE | | |
+-------+------------+--------------+--------------+-------------+-----------+--------- ----+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
mysql> show create table cli;
| cli | CREATE TABLE `cli` (
`idcli` bigint(255) NOT NULL AUTO_INCREMENT,
`cli` varchar(256) NOT NULL,
`type` enum('SDMF','MDMF') NOT NULL DEFAULT 'SDMF',
`priority` enum('realtime','high','normal','low','ignore') NOT NULL DEFAULT 'normal',
`status` enum('active','inactive','suspended','deleted') NOT NULL DEFAULT 'active',
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`description` text,
`charge` float DEFAULT '0',
`clitype` enum('chargemo','freemo') DEFAULT 'freemo',
PRIMARY KEY (`idcli`),
KEY `idx_cli` (`cli`),
KEY `cli_type_idx` (`clitype`)
) ENGINE=InnoDB AUTO_INCREMENT=117 DEFAULT CHARSET=latin1 |
1 row in set (0.00 sec)
mysql> show create table vendor;
| vendor | CREATE TABLE `vendor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(256) NOT NULL,
`company_name` varchar(256) DEFAULT NULL,
`phone_no` varchar(256) DEFAULT NULL,
`status` enum('active','inactive','suspended','deleted') DEFAULT 'active',
`mo` bigint(255) NOT NULL,
`mt` bigint(255) NOT NULL,
`used_mo` bigint(255) DEFAULT '0',
`used_mt` bigint(255) DEFAULT '0',
`start_time` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`end_time` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`secretkey` varchar(50) NOT NULL,
`callback_url` text,
`payment_callback_url` text,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`userid` int(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `secretkey_idx` (`secretkey`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 |
1 row in set (0.00 sec)
| subscriptionrequest | CREATE TABLE `subscriptionrequest` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT,
`ipaddress` varchar(256) CHARACTER SET latin1 NOT NULL DEFAULT '0.0.0.0',
`message` text,
`msisdn` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`mode` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`cli` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
`transactionid` varchar(100) DEFAULT NULL,
`secretkey` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`error_code` int(10) DEFAULT NULL,
`success` int(10) NOT NULL DEFAULT '0',
`status` enum('waiting','processing','completed','moexceeds','reject') DEFAULT 'waiting',
PRIMARY KEY (`id`),
KEY `idx_subreq_key` (`secretkey`),
KEY `idx_subreq_status` (`status`),
KEY `idx_subreq_transid` (`transactionid`),
KEY `idx_subreq_cli` (`cli`),
KEY `idx_subreq_date` (`date`)
) ENGINE=InnoDB AUTO_INCREMENT=1594161 DEFAULT CHARSET=utf8 |
FOR SETSUNA ---
mysql> explain SELECT DATE(sr.`date`) AS sr_date, v.company_name, c.cli,
-> COUNT(*) AS cnt, c.charge,
-> SUM(c.`charge`) AS charge_sum
-> FROM
-> subscriptionrequest AS sr
-> JOIN cli AS c ON sr.cli = c.cli
-> JOIN vendor AS v ON sr.secretkey = v.secretkey
-> WHERE
-> sr.`date` >= '2012-03-12' AND sr.`date` <= '2012-10-13'
-> AND c.clitype = 'chargemo'
-> GROUP BY DATE(sr.`date`), sr.secretkey, c.cli;
+----+-------------+-------+------+-----------------------------+----------------+--------- +---------------------------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------------------+----------------+--------- +---------------------------+-------+---------------------------------+
| 1 | SIMPLE | v | ALL | secretkey_idx | NULL | NULL | NULL | 9 | Using temporary; Using filesort |
| 1 | SIMPLE | sr | ref | idx_subreq_key,cli_date_idx | idx_subreq_key | 103 | crystal_du_sm.v.secretkey | 88746 | Using where |
| 1 | SIMPLE | c | ref | idx_cli,cli_type_idx | idx_cli | 258 | crystal_du_sm.sr.cli | 1 | Using where |
+----+-------------+-------+------+-----------------------------+----------------+--------- +---------------------------+-------+---------------------------------+
3 rows in set (0.00 sec)
--- 23/8/2012 ---
+----+-------------+-------+------+---------------------------------------+------------ -----+---------+----------------------------+-------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------------------------------+-----------------+---------+----------------------------+-------+-----------------+
| 1 | SIMPLE | v | ALL | secretkey_idx | NULL | NULL | NULL | 9 | Using temporary |
| 1 | SIMPLE | sr | ref | idx_subreq_key,idx_date_cli_secretkey | idx_subreq_key | 103 | crystal_du_sm.v.secretkey | 88608 | Using where |
| 1 | SIMPLE | c | ref | idx_cli_clitype | idx_cli_clitype | 260 | crystal_du_sm.sr.cli,const | 1 | Using where |
+----+-------------+-------+------+---------------------------------------+---------------- -+---------+----------------------------+-------+-----------------+
3 rows in set (0.00 sec)
答案 0 :(得分:1)
几句一般性评论:
我认为这个版本更具可读性
SELECT DATE(sr.`date`) AS sr_date, v.company_name, c.cli,
COUNT(*) AS cnt, c.charge,
SUM(c.`charge`) AS charge_sum
FROM
subscriptionrequest AS sr
JOIN cli AS c ON sr.cli = c.cli
JOIN vendor AS v ON sr.secretkey = v.secretkey
WHERE
sr.`date` >= '2012-03-12' AND sr.`date` <= '2012-10-13'
AND c.clitype = 'chargemo'
GROUP BY DATE(sr.`date`), sr.secretkey, c.cli;
您可能需要修改 subscriptionrequest 表:
ALTER TABLE subscriptionrequest DROP INDEX `idx_subreq_cli` , DROP INDEX
`idx_subreq_date`, ADD INDEX `cli_date` (`date`,`cli`);
这将有助于根据日期字段获取正确的记录子集,从而减少 subscriptionrequest 表中返回记录的数量。
编辑#1
架构修改&amp; (轻微)查询优化:
ALTER TABLE subscriptionrequest DROP INDEX `cli_date`,
ADD INDEX `idx_date_cli_secretkey` (`date`,`secretkey`,`cli`);
ALTER TABLE `cli` DROP INDEX idx_cli, DROP INDEX cli_type_idx,
ADD INDEX `idx_cli_clitype` (cli,clitype);
EXPLAIN SELECT DATE(sr.`date`) AS sr_date, v.company_name, c.cli,
COUNT(*) AS cnt, c.charge, SUM(c.`charge`) AS charge_sum
FROM subscriptionrequest AS sr JOIN
cli AS c ON sr.cli = c.cli JOIN vendor AS v ON sr.secretkey = v.secretkey
WHERE sr.`date` >= '2012-03-12' AND sr.`date` <= '2012-10-13'
AND c.clitype = 'chargemo' GROUP BY DATE(sr.`date`), sr.secretkey, c.cli
ORDER BY NULL\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: sr
type: index
possible_keys: idx_subreq_key,idx_date_cli_secretkey
key: idx_date_cli_secretkey
key_len: 160
ref: NULL
rows: 1
Extra: Using where; Using index; Using temporary
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: c
type: ref
possible_keys: idx_cli_clitype
key: idx_cli_clitype
key_len: 260
ref: so_12055859.sr.cli,const
rows: 1
Extra: Using where
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: v
type: ref
possible_keys: secretkey_idx
key: secretkey_idx
key_len: 52
ref: so_12055859.sr.secretkey
rows: 1
Extra: Using where
3 rows in set (0.01 sec)