使用同一条件字段,不同条件值,速度慢了很多,求解!

无聊的猪 2014-03-24 04:59:45
查询saledetail表,1月或3月的数据都很快15秒内能出来,但查2月份的数据就非常慢,要差不多2分钟,这些查询时间,都是在mysql刚启动完的时候试的,因为如果查过其它月份的数据后,缓存生效了再来查2月份或其它月份的时候,都只需要2秒不到了。

因为是测试数据,数据也不多,总数据50万条,其中1月份数据9万多条,2月份数据4万多,3月份数据5万多,查询条件sdate已建立索引。这问题很奇怪,也做过optimize table,问题依旧,查询脚本、表结构、索引、explain如下:

select * from saledetail where sdate>='2014-02-01' and sdate<='2014-02-28'; 


CREATE TABLE `saledetail` (
`detail_id` varchar(32) NOT NULL,
`sale_id` varchar(32) NOT NULL DEFAULT '',
`saleno` varchar(20) NOT NULL,
`items` int(11) NOT NULL,
`goodno` varchar(13) DEFAULT NULL,
`med_id` varchar(32) DEFAULT NULL,
`goodname` varchar(60) DEFAULT NULL,
`storeno` varchar(32) DEFAULT NULL,
`quantity` decimal(10,1) DEFAULT NULL,
`unitno` varchar(10) DEFAULT NULL,
`sprice` decimal(10,3) DEFAULT NULL,
`cost` decimal(10,4) DEFAULT NULL,
`discprice` decimal(10,3) DEFAULT NULL,
`discount` decimal(10,2) DEFAULT NULL,
`jlqty` int(10) DEFAULT NULL,
`djqty` decimal(10,3) DEFAULT NULL,
`mztypeno` varchar(3) DEFAULT NULL,
`gropno` char(10) DEFAULT NULL,
`updateby` varchar(32) DEFAULT NULL,
`updatebyid` varchar(32) DEFAULT NULL,
`updatedate` datetime DEFAULT NULL,
`cfsaleno` varchar(32) DEFAULT NULL,
`cfitemno` varchar(32) DEFAULT NULL,
`roundingfee` decimal(10,4) DEFAULT NULL,
`receivable` decimal(10,4) DEFAULT NULL,
`paidin` decimal(10,4) DEFAULT NULL,
`detail_type` int(5) DEFAULT NULL,
`account_type` varchar(5) DEFAULT NULL,
`spec` varchar(50) DEFAULT NULL,
`minqty` int(11) DEFAULT NULL,
`authorizer_id` varchar(32) DEFAULT NULL,
`batch_id` varchar(32) DEFAULT NULL,
`sale_type` smallint(1) DEFAULT NULL,
`sdate` datetime DEFAULT NULL,
PRIMARY KEY (`detail_id`),
KEY `sdate` (`sdate`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;




...全文
181 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
fcy_n 2014-03-25
  • 打赏
  • 举报
回复
1、mysql重启后,5.5版本及以下版本的innodb buffer是不缓存数据的,需要读一次数据,除非使用5.6版本 2、可以试下ANALYZE TABLE 3、如果不行,加上FORCE index试试
无聊的猪 2014-03-25
  • 打赏
  • 举报
回复
这样一直全表扫描的话 随着数据越来越多 又不能索引 那岂不是越来越慢
benluobo 2014-03-25
  • 打赏
  • 举报
回复
因为全表扫描的时候是顺序读取,是很好的IO读取方式 而索引扫描在不是主键索引的时候,会先定位索引位置,根据索引定位到主键位置,最后得到具体的数据,这些IO都属于随机读取 所以在扫描的数据很大的时候,有的时候全表扫描的效率比索引要好
无聊的猪 2014-03-25
  • 打赏
  • 举报
回复
引用 3 楼 ACMAIN_CHM 的回复:
注意一下where sdate>='2014-02-01' and sdate<='2014-02-28'; 的范围,当这个范围过大时,MYSQL认为大部分记录是符合条件的,则不会再走索引。
把索引去掉了以后 查2月份的数据也快了 但现在的疑问是 为什么走索引的时候 反而速度会慢了很多
ACMAIN_CHM 2014-03-24
  • 打赏
  • 举报
回复
注意一下where sdate>='2014-02-01' and sdate<='2014-02-28'; 的范围,当这个范围过大时,MYSQL认为大部分记录是符合条件的,则不会再走索引。
无聊的猪 2014-03-24
  • 打赏
  • 举报
回复
引用 1 楼 benluobobo 的回复:
第一 查询的时候 可以 在 select后面加上 sql_no_cache 这样就可以保证不使用缓存

第二 请问你的表是否做过分区?

第三 贴出1月份和2月份的explain对比


1、试过加 sql_no_cache 不过好像没有作用 查过一次以后还是会快,所以只好每次执行,都重启一下mysql。
2、没有做过表分区
3、1月份


2月份


这样看来好像1月的查询没有使用到索引呢
benluobo 2014-03-24
  • 打赏
  • 举报
回复
第一 查询的时候 可以 在 select后面加上 sql_no_cache 这样就可以保证不使用缓存 第二 请问你的表是否做过分区? 第三 贴出1月份和2月份的explain对比

56,678

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧