针对 store_name 字段

本文介绍了MySQL中如何创建和使用索引,以及如何避免索引失效。通过示例展示了全值匹配、最左前缀法则在查询优化中的应用,强调了不应在索引列上进行运算以及字符串需加单引号等注意事项,旨在提升SQL查询效率。

处理方案 , , 创建索引 :

create index product_list_stname on product_list(store_name);

索引创建完成之后,再次进行查询 :

SELECT * FROM product_list WHERE store_name = '联想北达兴科专卖店';

通过 explain , 查看执行计划,执行 SQL 时使用了刚才创建的索引

-- 查看SQL语句的执行计划
explain SELECT * FROM product_list WHERE store_name = '联想北达兴科专卖店';

5.2 索引的使用

5.2.1 准备环境

create table `tb_seller` (
	`sellerid` varchar (100),
	`name`  varchar (100) not null,
	`nickname` varchar (50),
	`password` varchar (60),
	`status`  varchar (1) not null,
	`address`  varchar (100) not null,
	`createtime` datetime,
    primary key(`sellerid`)
)engine=innodb default charset=utf8; 

insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('alibaba','阿里巴巴','阿里小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('baidu','百度科技有限公司','百度小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('huawei','华为科技有限公司','华为小店','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('itcast','传智播客教育科技有限公司','传智播客','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('itheima','黑马程序员','黑马程序员','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('luoji','罗技科技有限公司','罗技小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('oppo','OPPO科技有限公司','OPPO官方旗舰店','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('ourpalm','掌趣科技股份有限公司','掌趣小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('qiandu','千度科技','千度小店','e10adc3949ba59abbe56e057f20f883e','2','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('sina','新浪科技有限公司','新浪官方旗舰店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('xiaomi','小米科技','小米官方旗舰店','e10adc3949ba59abbe56e057f20f883e','1','西安市','2088-01-01 12:00:00');
insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('yijia','宜家家居','宜家家居旗舰店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00');


create index idx_seller_name_sta_addr on tb_seller(name,status,address);

5.2.2 避免索引失效

组合索引 (name,status,address)

1) 全值匹配

对索引中所有列都指定具体值。

-- 全值匹配
explain select * from tb_seller where name='小米科技' and status='1' and address='北京市';
ken_len = 3 * N + 2;
-- name varchar(100)  	==302
-- status varchar(1)  	==5
-- address varchar(100) ==302

2) 最左前缀法则

如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。

匹配最左前缀法则,走索引:

explain select * from tb_seller  where name='小米科技';  

违反最左前缀法则 , 索引失效:

explain select * from tb_seller  where status='1';
explain select * from tb_seller  where status='1'  and  address='北京市';

如果符合最左法则,但是出现跳跃某一列,只有最左列索引生效:

explain select * from tb_seller  where name='小米科技'  and  address='北京市';

3) 范围查询右边的列

-- 使用范围查询的情况,右边的列失效 
explain select * from tb_seller  where name='小米科技' and status='1'  and  address='北京市';
explain select * from tb_seller  where name='小米科技' and status>'1'  and  address='北京市';

根据前面的两个字段 name , status 查询是走索引的, 但是最后一个条件 address 没有用到索引。

4) 禁止列运算

-- 不要在索引列上进行运算操作, 索引将失效。
explain select * from tb_seller  where substring(name,3,2) ='科技';

5) 字符串不加单引号

造成索引失效。

-- 字符串不加单引号,造成索引失效。
explain select * from tb_seller  where name='科技' and status='0';
explain select * from tb_seller  where name='科技' and status=0;

由于,在查询时,没有对字符串加单引号,MySQL 的查询优化器,会自动的进行类型转换,造成索引失效。

要实现查询定位表 `cm_track_punch_copy1` 中人员丁美娟每组定位的停留时间,且按照指定的组统计规则进行统计,可以使用 SQL 来完成。以下是一个示例 SQL 代码,假设表中有 `person_name` 字段表示人员姓名,`store_code` 字段表示定位点,`punch_time` 字段表示打卡时间: ```sql -- 首先使用公共表表达式(CTE)对数据进行预处理 WITH grouped_punches AS ( -- 对表 cm_track_punch_copy1 进行筛选,只选择人员为丁美娟的数据 SELECT person_name, store_code, punch_time, -- 使用 ROW_NUMBER() 函数为每个定位点的打卡记录分配一个唯一的行号 ROW_NUMBER() OVER (PARTITION BY person_name, store_code ORDER BY punch_time) as rn, -- 使用 LAG() 函数获取上一次的打卡时间 LAG(punch_time) OVER (PARTITION BY person_name, store_code ORDER BY punch_time) as prev_punch_time FROM cm_track_punch_copy1 WHERE person_name = '丁美娟' ), grouped_data AS ( SELECT person_name, store_code, punch_time, rn, prev_punch_time, -- 判断是否需要重新开始计时 CASE -- 如果是该定位点的第一条记录,或者相邻打卡时长大于 30 分钟,或者相邻打卡时间中间有不同打卡记录,则标记为新的一组 WHEN rn = 1 OR (punch_time - prev_punch_time) > INTERVAL '30 minutes' THEN 1 ELSE 0 END as new_group FROM grouped_punches ), grouped_with_group_id AS ( SELECT person_name, store_code, punch_time, -- 使用 SUM() 函数对 new_group 进行累积求和,为每组分配一个唯一的组 ID SUM(new_group) OVER (PARTITION BY person_name, store_code ORDER BY punch_time) as group_id FROM grouped_data ) -- 从最终的分组数据中计算每组的停留时间 SELECT person_name, store_code, group_id, -- 计算每组的最大打卡时间和最小打卡时间的差值,即为停留时间 MAX(punch_time) - MIN(punch_time) as stay_time FROM grouped_with_group_id GROUP BY person_name, store_code, group_id ORDER BY person_name, store_code, group_id; ``` ### 代码解释 1. **`grouped_punches` CTE**:对表 `cm_track_punch_copy1` 进行筛选,只选择人员为丁美娟的数据,并为每个定位点的打卡记录分配一个唯一的行号,同时使用 `LAG()` 函数获取上一次的打卡时间。 2. **`grouped_data` CTE**:根据 `grouped_punches` 中的数据,判断是否需要重新开始计时,并标记为新的一组。 3. **`grouped_with_group_id` CTE**:使用 `SUM()` 函数对 `new_group` 进行累积求和,为每组分配一个唯一的组 ID。 4. **最终查询**:从 `grouped_with_group_id` 中计算每组的停留时间,即最大打卡时间和最小打卡时间的差值。 ### 注意事项 - 上述代码中的 `punch_time` 字段假设为 `TIMESTAMP` 类型,如果实际情况不同,可能需要进行相应的调整。 - 不同的数据库系统对于时间间隔的计算和函数的使用可能会有所不同,需要根据实际使用的数据库进行调整。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值