我继承的一些数据库/查询有问题。这是针对一些大型数据集和对它们进行的报告。
我正在尝试调整和调整以获得一些改进。
发生的事情是我不是 100% 清楚 MySQL 如何决定使用哪个索引。
为什么下面列出的第一个查询不使用查询 2 中使用的索引。在查询 2 中,我正在做我假设查询引擎应该做的事情,获取小表,获取适当的值,然后应用它们搜索更大的表,并利用适当的索引。
我在这里做错了什么?或者更确切地说,我对外键、索引和连接在这里的工作方式有什么误解:)
这是2个相关表
表 1
~450 行
CREATE TABLE `client_accounts_dim` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`client_id` int(10) unsigned NOT NULL,
`service_provider_id` int(10) unsigned NOT NULL,
`account_number` varchar(45) NOT NULL,
`label` varchar(128) DEFAULT NULL,
`service_provider_name` varchar(45) NOT NULL,
`client_name` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
KEY `client_id` (`client_id`,`account_number`)
) ENGINE=InnoDB;
表 2
~11,000,000 行
CREATE TABLE `invoices_fact` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_number` varchar(45) NOT NULL COMMENT ' ',
...
...
`tracking_number` varchar(45) DEFAULT NULL,
`division_id` int(11) DEFAULT NULL,
`client_accounts_dim_id` int(10) unsigned NOT NULL,
`invoice_date_dim_id` bigint(20) DEFAULT NULL,
`shipment_date_dim_id` bigint(20) NOT NULL,
`received_date_dim_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_invoice_details_client_accounts_dim1_idx` (`client_accounts_dim_id`),
KEY `invoice_date_dim_id` (`invoice_date_dim_id`),
KEY `shipment_date_dim_id` (`shipment_date_dim_id`,`client_accounts_dim_id`,`division_id`,`tracking_number`),
CONSTRAINT `fk_invoice_details_client_accounts_dim1` FOREIGN KEY (`client_accounts_dim_id`) REFERENCES `client_accounts_dim` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB;
第一个查询我在哪里进行基本连接
SELECT count(distinct tracking_number) as val, p.division_id as division_id
FROM client_accounts_dim c, invoices_fact p
WHERE c.id = p.client_accounts_dim_id
AND p.division_id IN (2,3,7)
AND c.client_id = 17
AND p.shipment_date_dim_id between 20120101 and 20121108
GROUB BY p.division_id;
28 秒内运行
解释产量
+----+-------------+-------+------+------------------------------------------------------------------+---------------------------------------------+---------+---------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+------------------------------------------------------------------+---------------------------------------------+---------+---------+------+-------------+
| 1 | SIMPLE | c | ref | PRIMARY,client_id | client_id | 4 | const | 49 | Using index |
| 1 | SIMPLE | p | ref | fk_package_details_client_accounts_dim1_idx,shipment_date_dim_id | fk_package_details_client_accounts_dim1_idx | 4 | c.id | 913 | Using where |
+----+-------------+-------+------+------------------------------------------------------------------+---------------------------------------------+---------+---------+------+-------------+
通过首先运行查询,然后将 client_accounts_dim_ids 放入,查询我“手动”在哪里进行连接。
SELECT count(distinct tracking_number) as val, p.division_id as division_id
FROM invoices_fact p
WHERE division_id in (2,3,7)
AND p.client_accounts_dim_id IN ( 232, 233, 234, 277, 235, 236, 279, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 278, 280, 262, 263, 264, 252, 256, 254, 259, 261, 257, 266, 276, 267, 255, 258, 274, 273, 272, 271, 269, 270, 268, 275, 253, 265, 260 )
AND p.shipment_date_dim_id between 20120101 and 20121108
GROUP BY p.division_id;
在 1.6 秒内运行
解释产量:
+----+-------------+-------+-------+------------------------------------------------------------------+------------------------+---------+------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+------------------------------------------------------------------+------------------------+---------+------+---------+--------------------------+
| 1 | SIMPLE | p | range | fk_package_details_client_accounts_dim1_idx,shipment_date_dim_id | shipment_date_dim_id | 19 | NULL | 4991810 | Using where; Using index |
+----+-------------+-------+-------+------------------------------------------------------------------+------------------------+---------+------+---------+--------------------------+