如何分析 mysql 不走索引的情况

Create Table: CREATE TABLE `tab` (
`id` int(10) NOT NULL auto_increment,
`type` char(16) NOT NULL,
PRIMARY KEY
KEY `t` (`type`)) ENGINE=MyISAM
执行的sql为:
select id,type from tab group by type
执行计划:
请教下大家,为什么是全表扫描,怎么没有使用使用 t索引 ?
该问题被发起重新开启投票
投票剩余时间:
之前被关闭原因:
该问题被发起删除投票
投票剩余时间:
距离悬赏到期还有:
参与关闭投票者:
关闭原因:
该问题已经被锁定
锁定原因:()
保护原因:避免来自新用户不合宜或无意义的致谢、跟帖答案。
该问题已成功删除,仅对您可见,其他人不能够查看。
去掉id字段就可以了 查询字段必须和group by 保持一致group by 使用索引有两种情况:1、使用松散索引实现,即mysql完全使用索引扫描实现group by操作,更直接的说,就是sql语句中所有的字段都在同一个索引中,需要满足一下几个条件:
group by的条件字段必须在同一个索引中最前面的连续位置;
使用group by的同时,只能使用max和min连个聚合函数(B+);
如果引用到该索引中group by条件之外的字段的时候,必须以常量的形式存在;2、使用紧凑索引扫描实现,即读取所有满足条件的索引键,然后再根据读取后的数据来完成 GROUP BY 操作得到相应结果。
在做mysql 数据优化的时候讲到GROUP BY的优化,下面是GROUP BY 没用索引的情况。
对不同的索引键做 GROUP BY
在非连续的索引键部分上做 GROUP BY
用于搜索记录的索引键和做 GROUP BY 的不是同一个
还有一种情况,也是我们经常犯错误的应用:查询字段必须和后面GROUP BY 一致这样才能用到索引,正如你上面sql!
你的问题是对GROUP BY索引的应用不清楚,下面是以前总结的东西,希望对你有帮助一、GROUP BY 的索引应用1、查询字段必须和后面GROUP BY 一致select TeamID from competeinfo where TeamID &10 group by TeamID。这里就是通过TeamID 来查找。完成group by 。2、联合索引的应用,切记注意GROUP BY 顺序,Where 条件和GROUP BY 字段得是一个索引里面的
这个表CompeteID,TeamID建立联合索引 1)select TeamID from competeinfo where TeamID &10 and CompeteID & 100020 group by CompeteID
这个查询用到了CompeteID,TeamID联合索引 2)select TeamID from competeinfo where TeamID &10 and CompeteID & 100020 group by TeamID
这样的话查询group by中就没有用到索引了二、下面是总结的是联合索引的使用Index(Name,Age)表示在Name,Age两列上建立联合索引如果where name='pp' 能使用索引where age=25时不能使用索引where name='pp' and age&25 能使用索引 where name ='pp'
能使用索引where
order by age
不能使用索引where
order by name,age
能使用索引order by name asc age desc 将不能使用索引!
不是您所需,查看更多相关问题与答案
德问是一个专业的编程问答社区,请
后再提交答案
关注该问题的人
共被浏览 (5029) 次查看: 1481|回复: 9
一个查询的where列如果多于3个,是不是不走索引更好!有例子,希望大家积极讨论一下。
论坛徽章:3
一个生产库的慢日志记录的sql:
select accountmod0_.account_id as account1_0_, accountmod0_.account_type_id as account2_0_, accountmod0_.hotel_id as hotel3_0_, accountmod0_.hotelgroup_id as hotelgroup4_0_, accountmod0_.register_id as register5_0_, accountmod0_.guest_id as guest6_0_, accountmod0_.group_id as group7_0_, accountmod0_.company_id as company8_0_, accountmod0_.money as money0_, accountmod0_.payment_method_id as payment10_0_, accountmod0_.is_reversed as is11_0_, accountmod0_.is_balanced as is12_0_, accountmod0_.from_account_id as from13_0_, accountmod0_.to_account_id as to14_0_, accountmod0_.cash_bill_no as cash15_0_, accountmod0_.shift_id as shift16_0_, accountmod0_.account_date as account17_0_, accountmod0_.created_at as created18_0_, accountmod0_.note as note0_, accountmod0_.hotel_operator_id as hotel20_0_, accountmod0_.pos_site_id as pos21_0_, accountmod0_.room_order_id as room22_0_, accountmod0_.close_date as close23_0_, accountmod0_.close_shift_id as close24_0_, accountmod0_.close_hotel_operator_id as close25_0_, accountmod0_.updated_at as updated26_0_, accountmod0_.credit_card_type_id as credit27_0_, accountmod0_.account_page as account28_0_, accountmod0_.ar_date as ar29_0_, accountmod0_.ar_shift_id as ar30_0_, accountmod0_.ar_operator_id as ar31_0_, accountmod0_.is_hedged as is32_0_, accountmod0_.source_room_id as source33_0_, accountmod0_.hedge_date as hedge34_0_, accountmod0_.hedge_account_id as hedge35_0_, accountmod0_.foreign_currency_code as foreign36_0_, accountmod0_.foreign_money as foreign37_0_, accountmod0_.card_type_id as card38_0_, accountmod0_.card_no as card39_0_, accountmod0_.voucher_type_id as voucher40_0_, accountmod0_.voucher_no as voucher41_0_, accountmod0_.owner_id as owner42_0_, accountmod0_.owner_type as owner43_0_, accountmod0_.balance_no as balance44_0_, accountmod0_.ar_no as ar45_0_, accountmod0_.meeting_room_id as meeting46_0_, accountmod0_.sign_guest as sign47_0_, accountmod0_.res_revenue_group_id as res48_0_, accountmod0_.res_discount_id as res49_0_, accountmod0_.credit_card_no as credit50_0_, accountmod0_.phone_bill_id as phone51_0_, accountmod0_.product_bill_id as product52_0_ from accounts as accountmod0_&&where 1=1 and accountmod0_.hotel_id='cnbjbjb132' and accountmod0_.account_type_id=10 and (accountmod0_.shift_id=3 or accountmod0_.shift_id=3+10) and accountmod0_.account_date&='' order by accountmod0_.account_id desc limit 18; 其执行计划: id | select_type | table& && &&&| type&&| possible_keys& && && &&&| key& &&&| key_len | ref&&| rows | Extra& && & |
+----+-------------+--------------+-------+-------------------------+---------+---------+------+------+-------------+
|&&1 | SIMPLE& && &| accountmod0_ | index | FK_R_NA,FK_R_OG,FK_R_QV | PRIMARY | 77& && &| NULL | 5094 | Using where |
+----+-------------+--------------+-------+-------------------------+---------+- 执行时间超过1分钟。大家觉得有优化的余地吗?怎么走索引或者不走?
论坛徽章:6
手动将or改成UNION ALL试试。不过5.0后会自动将or变成union了。不要在where之后出现3+10这样的运算,给个定值。
将where后面的字段,包括order by后面的字段都加入联合索引中。
好多字段,有不需要的大字段没,数据是否也很多,考虑水平垂直切分下。
论坛徽章:3
我的mysql版本时5.5的。accounts表目前有2千万条左右。我觉得主要考虑一下索引问题,建立了联合索引,但是并不能走。
论坛徽章:1
楼主 可以看看 这个帖子&&
论坛徽章:3
现在的情况是hotel_id有索引,account_type_id有索引,account_date和hotel_id建立的联合索引。我希望能走index merge,但却扫描了主键索引。一个原因是mysql好像不能有3个索引merge。
论坛徽章:6
show create table accounts来看下
论坛徽章:3
rushm 发表于
show create table accounts来看下
mysql& show create table accounts\G
*************************** 1. row ***************************
& && & Table: accounts
Create Table: CREATE TABLE `accounts` (
&&`account_id` varchar(25) NOT NULL,
&&`account_type_id` int(11) NOT NULL,
&&`hotel_id` char(10) DEFAULT NULL,
&&`register_id` varchar(25) DEFAULT NULL,
&&`guest_id` varchar(50) DEFAULT NULL,
&&`group_id` varchar(50) DEFAULT NULL,
&&`company_id` int(11) DEFAULT NULL,
&&`money` double NOT NULL,
&&`phone_bill_id` varchar(50) DEFAULT NULL,
&&`product_bill_id` varchar(50) DEFAULT NULL,
&&`payment_method_id` tinyint(4) DEFAULT NULL,
&&`is_reversed` tinyint(1) NOT NULL DEFAULT '0',
&&`is_balanced` tinyint(1) DEFAULT '0',
&&`from_account_id` varchar(25) DEFAULT NULL,
&&`to_account_id` varchar(25) DEFAULT NULL,
&&`cash_bill_no` varchar(25) DEFAULT NULL,
&&`shift_id` tinyint(4) DEFAULT NULL,
&&`account_date` date NOT NULL,
&&`created_at` datetime DEFAULT NULL,
&&`note` varchar(255) DEFAULT NULL,
&&`hotel_operator_id` varchar(50) NOT NULL,
&&`pos_site_id` int(11) DEFAULT NULL,
&&`room_order_id` varchar(50) DEFAULT NULL,
&&`close_date` date DEFAULT NULL,
&&`close_shift_id` tinyint(4) DEFAULT NULL,
&&`close_hotel_operator_id` varchar(50) DEFAULT NULL,
&&`updated_at` datetime DEFAULT NULL,
&&`credit_card_type_id` int(11) DEFAULT NULL,
&&`account_page` tinyint(4) DEFAULT '0',
&&`ar_date` date DEFAULT NULL,
&&`ar_shift_id` tinyint(4) DEFAULT NULL,
&&`ar_operator_id` varchar(50) DEFAULT NULL,
&&`is_hedged` tinyint(1) NOT NULL DEFAULT '0',
&&`source_room_id` int(11) DEFAULT NULL,
&&`hedge_date` date DEFAULT NULL,
&&`hedge_account_id` varchar(25) DEFAULT NULL,
&&`foreign_currency_code` varchar(10) DEFAULT NULL,
&&`foreign_money` double DEFAULT NULL,
&&`card_type_id` varchar(25) DEFAULT NULL,
&&`card_no` varchar(25) DEFAULT NULL,
&&`voucher_type_id` varchar(25) DEFAULT NULL,
&&`voucher_no` varchar(25) DEFAULT NULL,
&&`owner_id` varchar(25) DEFAULT NULL,
&&`owner_type` tinyint(4) DEFAULT NULL,
&&`hotelgroup_id` varchar(50) DEFAULT NULL,
&&`meeting_room_id` int(11) DEFAULT NULL,
&&`balance_no` varchar(25) DEFAULT NULL,
&&`ar_no` varchar(25) DEFAULT NULL,
&&`sign_guest` varchar(50) DEFAULT NULL,
&&`res_revenue_group_id` int(11) DEFAULT NULL,
&&`res_discount_id` int(11) DEFAULT NULL,
&&`credit_card_no` varchar(25) DEFAULT NULL,
&&PRIMARY KEY (`account_id`),
&&KEY `FK_R_LT` (`phone_bill_id`),
&&KEY `FK_R_LX` (`from_account_id`),
&&KEY `FK_R_LY` (`to_account_id`),
&&KEY `FK_R_LZ` (`hotel_operator_id`),
&&KEY `FK_R_MQ` (`product_bill_id`),
&&KEY `FK_R_NA` (`account_type_id`),
&&KEY `FK_R_OE` (`room_order_id`),
&&KEY `FK_R_NV` (`group_id`),
&&KEY `FK_R_NU` (`register_id`),
&&KEY `FK_R_NS` (`company_id`),
&&KEY `FK_R_OG` (`hotel_id`,`updated_at`),
&&KEY `owner_id` (`owner_id`),
&&KEY `FK_R_FX` (`hotelgroup_id`),
&&KEY `FK_R_IQ` (`meeting_room_id`),
&&KEY `FK_R_NR` (`pos_site_id`),
&&KEY `FK_R_KF` (`res_revenue_group_id`),
&&KEY `voucher_type_id` (`voucher_type_id`),
&&KEY `FK_R_QV` (`account_date`,`hotel_id`),
&&KEY `idx_close_date` (`close_date`,`hotel_id`),
&&KEY `idx_bill` (`cash_bill_no`,`hotel_id`),
&&KEY `idx_guest` (`guest_id`),
&&KEY `idx_ar_date` (`ar_date`,`hotel_id`),
&&KEY `idx_card` (`card_type_id`,`card_no`),
&&CONSTRAINT `FK_R_FX` FOREIGN KEY (`hotelgroup_id`) REFERENCES `hotelgroups` (`hotelgroup_id`),
&&CONSTRAINT `FK_R_IQ` FOREIGN KEY (`meeting_room_id`) REFERENCES `meeting_rooms` (`id`),
&&CONSTRAINT `FK_R_KF` FOREIGN KEY (`res_revenue_group_id`) REFERENCES `res_revenue_groups` (`id`),
&&CONSTRAINT `FK_R_LZ` FOREIGN KEY (`hotel_operator_id`) REFERENCES `users` (`user_id`),
&&CONSTRAINT `FK_R_MQ` FOREIGN KEY (`product_bill_id`) REFERENCES `product_bills` (`id`),
&&CONSTRAINT `FK_R_NA` FOREIGN KEY (`account_type_id`) REFERENCES `account_types` (`id`),
&&CONSTRAINT `FK_R_NR` FOREIGN KEY (`pos_site_id`) REFERENCES `pos_sites` (`id`),
&&CONSTRAINT `FK_R_NS` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`),
&&CONSTRAINT `FK_R_NU` FOREIGN KEY (`register_id`) REFERENCES `registers` (`id`),
&&CONSTRAINT `FK_R_NV` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`),
&&CONSTRAINT `FK_R_OG` FOREIGN KEY (`hotel_id`) REFERENCES `hotels` (`hotel_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
论坛徽章:6
本帖最后由 rushm 于
13:46 编辑
ifeelstupid 发表于
mysql& show create table accounts\G
*************************** 1. row ************************** ...
索引方面:含null值的联合索引是无效的。试试where后面的字段建个联合,用sql_no_cache调试,强制走索引试试效率有没快。
建议将DEFAULT NULL替换成NOT NULL DEFAULT 0
表体积:还有这表也太不苗条了吧,字段多,约束多,为了效率得瘦下身
论坛徽章:3
rushm 发表于
索引方面:含null值的联合索引是无效的。试试where后面的字段建个联合,用sql_no_cache调试,强制走索引试 ...
嗯,好的,谢谢。我测试了很多索引结果,发现有个速度很快,索引现在优化结果是比较明显的。至于你说的对表对象瘦身,我也觉得很有必要,因为这个表的数据每天都在增。但是请问一下,你有什么好的方法吗?最好能具体点,因为在实际生产中,对大表瘦身还没做过。
论坛徽章:6
ifeelstupid 发表于
嗯,好的,谢谢。我测试了很多索引结果,发现有个速度很快,索引现在优化结果是比较明显的。至于你说的对 ...
结构or数据拆分,分好多种方式啊,维护停机肯定要的,得找开发配合弄,商量哪种维护成本低就用那种
itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有    
 北京市公安局海淀分局网监中心备案编号: 广播电视节目制作经营许可证:编号(京)字第1149号

我要回帖

更多关于 mysql 视图不走索引 的文章

 

随机推荐