有没有用到索引,是看Key那一栏,而不是possible_key
索引失效的原因有很多,
大哥我知道是看key,我圈起来possible_key是为了说明这两张边上是有索引(主键)
是啊,所以说,存在索引失效的问题。
这个需要你自己看下什么情况导致的啊,单纯看sql,是看不出来的。
没有表结构等
order by 字段 使用含索引的字段。如主键id
order by 子句的列是有索引的 图中也贴出了建索引的SQL。好的,谢谢兄台,我再看看。
有些索引是没用的。你建的时间索引明显没用到。可能用到的索引里面都没包含那个时间索引
你试试用id把,如果还没解决的话,可以把表发给我。我有空帮你看看
谢谢,表结构如下:
CREATE DATABASE `demo` ;
USE `demo`;
CREATE TABLE `tm_order_info` (
`id` varchar(50) NOT NULL,
`goods_id` varchar(20) DEFAULT NULL,
`user_id` varchar(50) NOT NULL,
`univalence` int(11) DEFAULT NULL,
`money` int(11) DEFAULT NULL,
`num` int(11) DEFAULT '1',
`status` int(11) DEFAULT '1',
`order_num` varchar(100) DEFAULT NULL,
`pay_date` timestamp NULL DEFAULT NULL,
`create_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `tm_order_info`(`id`,`goods_id`,`user_id`,`univalence`,`money`,`num`,`status`,`order_num`,`pay_date`,`create_date`) values ('1','1','1',12345678,1234,1,1,'123123','2020-07-10 18:44:55','2020-07-10 18:44:58'),('98803754616292453','1','1',12345678,12366191,1,1,'123123','2020-07-08 18:44:55','2020-07-10 18:45:57');
CREATE TABLE `tm_send_records` (
`id` varchar(20) NOT NULL COMMENT '主键ID',
`order_id` varchar(20) NOT NULL COMMENT '订单ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into `tm_send_records`(`id`,`order_id`) values ('1','1');
CREATE TABLE `tm_trademark` (
`id` varchar(20) NOT NULL,
`name` varchar(20) NOT NULL,
`image` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `tm_trademark`(`id`,`name`,`image`) values ('1','阿斯顿发送到','https://xxx.oss-cn-zhangjiakou.aliyuncs.com/icon/trademark/20200709/66925599999500.jpg');
CREATE TABLE `tm_user_info` (
`id` varchar(50) NOT NULL,
`phone` varchar(50) NOT NULL,
`nikename` varchar(500) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
insert into `tm_user_info`(`id`,`phone`,`nikename`) values ('1','13309272164','非法字符');
查询语句:
SELECT
toi.id,
toi.status,
toi.univalence,
toi.num,
toi.money,
toi.order_num,
toi.pay_date pay_time,
toi.create_date create_time,
'微信支付' pay_type,
(SELECT COUNT(0) FROM tm_send_records tsr WHERE tsr.order_id = toi.id) remaining,
# 显示关联列则索引失效
tt.image,
tt.name,
tui.phone,
tui.nikename
FROM
tm_order_info toi
LEFT JOIN tm_user_info tui ON toi.`user_id` = tui.`id`
LEFT JOIN tm_trademark tt ON toi.`goods_id` = tt.`id`
LIMIT 20;
我什么都没动
你试着把order_info表的数据多复制几条呢?
你给tm_order_info表建一个组合索引(user_id,goods_id)
今天没空了。该下班了
好,我晚上回去试试,谢谢?
这种时候,你加where 条件 create_date 排除掉 大部分数据,查看执行计划,你会发现 你的索引被用上了
我做过这个尝试,在tm_order_info表的数据量很少的时候,确实会发现索引生效了,但是当数据量超过20条的时候就还是变成了use join buffer (BNL)了。实在是搞不懂啊~
我觉得也许我可以通过Cardinality来得出答案。
你排序了,然而没有 where 帮你检索掉 大部分数据,所以就需要全表扫描了,数据库 优化机制默认会认为使用索引会更慢,所以就不会使用了
其实我更疑问的是,如果再关联查询的时候,我在查询结果中加入了关联表的非主键字段之后就会导致索引失效。但是类似于"select a.name, b.dept_name from a left join b on a.dept_id = b.id"这样的SQL不是经常会用到的关联查询吗?难道这种写法有什么问题吗?
在多表查询中,一般使用组合索引进行查询的。考虑对select 、where、order by中的字段添加索引
你的意思是在这条语句中(select a.name, b.dept_name from a left join b on a.dept_id = b.id)对b表的dept_name加索引吗?
dept_id和name
那么对于这样的业务逻辑,还有其它的处理方式吗?因为如果这样的话,当结果集出现的关联字段较多的话,可能会出现维护索引过多的问题吧?
所以,索引要选那种筛选性较大的字段