高效查询方法

随着数据量的增大,企业对查询的速度要求也越来越高,掌握高效查询的方法对于平时的工作是非常有帮助的。下面我们就一起来看一下有哪些方法可以高效查询。

为了提高数据的查询速度,最常用的解决方案就是给表中变量创建索引。我们可以将索引理解成书的目录,如果一本书没有目录,那检索起来可能就比较麻烦,一旦有了目录,我们就可以根据目录进行索引,很快地找到我们需要的内容。同样的道理,如果数据表中有了索引,就可以大大提高MySQL的执行效率。

1. 常见索引类型

索引有很多种类型,下面我们一起来学习几个比较常用的索引类型。
(1)普通索引
普通索引是一种没有任何约束的索引,它对表中变量的值不做任何的限制,不管变量的值是否存在重复值或缺失值(也就是NULL值),所以普通索引是使用最频繁的一种索引。

可以通过两种方式来建立普通索引:

  • 创建新表时设定某个字段为普通索引
  • 基于已有的表添加普通索引
# 两种普通索引的创建方法
# 建表时创建索引
CREATE TABLE <table_name_>
( field1 data_type1, field2 data_type2, field3 data_type3, ……
INDEX <index_name>(field1));
# 对已有表添加索引,可以通过创建法或修改法
CREATE INDEX <index_name> ON <table_name_>(field_list); #基于已有的表创建索引
ALTER TABLE <table_name_> ADD INDEX <index_name> (field_list); #基于已有表修改索引

以校园一卡通消费数据stu_card为例,查询出交易时间在2013年9月1日的所有记录。

# 没有创建索引之前的条件查询
SELECT * FROM stu_card
WHERE custom_date BETWEEN '2013-09-01 00:00:00' AND '2013-09-01 23:59:59';

结果显示,1200万行数据,查询出满足条件的3万多行数据大约需要14.907s的时间。

# 创建索引
CREATE INDEX date_index ON stu_card(custom_date);
# 执行查询
SELECT * FROM stu_card
WHERE custom_date BETWEEN '2013-09-01 00:00:00' AND '2013-09-01 23:59:59';

结果显示,基于普通索引的查询代码,获取满足条件的交易记录只需要0.1秒左右,速度有明显提升。
(2)唯一索引
相对于普通索引来说,唯一索引对字段或者字段组合是有约束的,也就是必选确保字段或者字段组合的每一个观测值都是唯一的,不能存在重复值。如果字段中还有多个空白字符串,也算是有重复值,因为空字符串代表一种值。

一个表中可以有多个唯一索引,创建唯一索引的方法也有两种,与创建普通索引类似。可以在创建新表的时候设置唯一索引,也可以对已有表添加唯一索引。

# 两种唯一索引的创建方法
# 建表时创建索引
CREATE TABLE <table_name_>
( field1 data_type1, field2 data_type2, field3 data_type3, ……UNIQUE <index_name>(field1,field2)); # 对已有表添加索引,可以通过创建法或修改法
CREATE UNIQUE INDEX <index_name> ON <table_name_>(field_list); #基于已有的表创建索引
ALTER TABLE <table_name_> ADD UNIQUE <index_name> (field_list); #基于已有表修改索 引

接下来以某平台的旅游交易数据为例,对比无索引和基于唯一索引的两种查询的速度。

# 新建数据表tourism_orders
CREATE TABLE tourism_orders(
userid VARCHAR(20),
orderid VARCHAR(12),
orderTime VARCHAR(15),
orderType VARCHAR(2),
city VARCHAR(20),
country VARCHAR(20),
continent VARCHAR(10));
# 往表中插数据
LOAD DATA local INFILE '/Users/zhucan/Desktop/tourism_orders.csv'
INTO TABLE tourism_orders
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
# 查询数据前几行
SELECT * FROM tourism_orders
LIMIT 10;
# 无索引下的条件查询
SELECT * FROM tourism_orders WHERE userid = '100000001445';
# 约0.016秒
# 创建两个组合变量的唯一索引
CREATE UNIQUE INDEX id_idx ON tourism_orders(userid, orderid);
# 再次执行查询语句
SELECT * FROM tourism_orders
WHERE userid = '100000001445';  # 几乎为0秒

(3)主键索引
主键索引对字段的要求最为严格,必须确保字段中的值既不存在重复值也不存在缺失值。与普通索引和唯一索引不同的是,一张表中只能有一个主键索引。关于主键索引的创建语法:

# 两种主键索引的创建方法 # 建表时创建索引
CREATE TABLE <table_name_>
( field1 data_type1, field2 data_type2, field3 data_type3, ……
PRIMARY KEY <index_name>(field1,field2));
# 对已有表添加索引
ALTER TABLE <table_name_> ADD PRIMARY KEY <index_name>(field_list); #基于已有表修改索引

这里使用用户注册数据和用户交易数据,来验证主键索引构建前后查询速度的差异。

# 创建用户注册表和RFM表
CREATE TABLE regit_info
(
uid VARCHAR(10),
gender TINYINT,
age TINYINT,
regit_date DATE
);
CREATE TABLE RFM
(
uid VARCHAR(10),
R INT,
F TINYINT,
M DECIMAL(10,2)
);
# 批量导入数据
LOAD DATA local INFILE '/Users/zhucan/Desktop/regit_info.csv'
INTO TABLE regit_info
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS; LOAD DATA local INFILE '/Users/zhucan/Desktop/RFM.csv'
INTO TABLE RFM
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 ROWS; # 内连接完成两表字段的合并
SELECT t1.*,t2.R,t2.F,t2.M FROM regit_info AS t1
INNER JOIN RFM AS t2
ON t1.uid=t2.uid
LIMIT 10000;
# 添加主键索引
ALTER TABLE regit_info ADD PRIMARY key (uid);
ALTER TABLE RFM ADD PRIMARY key (uid);
# 再次执行查询
SELECT t1.*,t2.R,t2.F,t2.M
FROM regit_info AS t1
INNER JOIN RFM AS t2
ON t1.uid=t2.uid

2. 索引的查询

如果想要对表进行操作,通常需要知道表中是否已经存在索引,如果存在这些索引又是什么类型的,名称是什么,是设置在哪些字段上了等等。只有了解表中的索引信息,我们才能进一步管理索引。

# 查询索引信息语法
SHOW INDEX FROM <table_name_>;

查询用户注册表regit_info和旅游交易表tourism_orders的索引信息:

SHOW INDEX FROM regit_info;
SHOW INDEX FROM tourism_orders;

3. 删除索引

# 删除索引语法
DROP INDEX <index_name> ON <table_name_>;
#用于删除普通索引和唯一索引
ALTER TABLE <table_name_> DROP INDEX <index_name>;
#用于删除普通索引和唯一索引
ALTER TABLE <table_name_> DROP PRIMARY KEY; #用于删除主键索引

删除用户注册表regit_info中的主键索引:

ALTER TABLE regit_info DROP PRIMARY KEY; #删除索引
SHOW INDEX FROM regit_info; #查看索引

删除旅游交易表tourism_orders中的唯一索引:

DROP INDEX id_idx ON tourism_orders; #删除索引
SHOW INDEX FROM tourism_orders; #查看索引

4 . 关于索引的注意事项

尽管索引有提速的功能(可以提高响应的select的效率),但是也不能滥用,因为它会降低数据表的写操作速度(insert 和 update的效率会变低),也会占用一定的磁盘空间。所以在创建和使用索引的过程
中,有一些事项需要大家注意:

4.1 何时创建索引

  • WHERE 关键词后面的字段创建索引,可以加快条件判断速度
  • ORDER BY关键词后面的字段创建索引,可以加快排序速度
  • 表连接关键词 ON 后面的字段创建索引,可以加快表连接速度
  • 包含大量NULL的字段不适合创建索引,因为索引不可以包含NULL值
  • 包含大量重复值的字段不适合创建索引,因为基于索引的查询规则,在进行条件筛选的时候
  • 可能会产生大量的数据行,此时索引并不能加快数据库搜索过程中的扫描速度

4.2 索引无效的情况

  • WHERE 关键词后面的条件表达式中如果使用IN、OR、!=或者<>,均会导致索引无效。解决方法是将“!=”或者“<>”替换为">AND<",将"IS NOT NULL"替换为">=CHR(0)"。
  • 筛选或排序过程中,如果对索引列使用函数,则索引失效。
  • 筛选过程中,如果字符型字段写成了数值型的数字,则索引失效(比如,用户id字段是字符型,那筛选的时候需要写where uid = “1”)
  • 使用模糊查询的时候,如果将通配符放在开头,则索引失效(like “%aaa%” 不会使用索引而like“aaa%”可以使用索引)
  • 对于多列的组合索引,遵循左原则,例如对字段A,B,C设置索引 INDEX(A,B,C) ,则"A>0" “A=1 AND B>10”、“A=10 AND B<6 AND C>100"都可以使组合索引有效,但是"B>10”、"B<6 AND C>100"都会导致组合索引失效。
  • 在JOIN操作中,关键词ON后面的字段类型要保持一致(也就是左表中这个字段的数据类型和右表中同一字段的数据类型要保持一致),否则索引无效。

4.3 索引数量并不是越多越好

原则上,一个表的索引数量最好不要超过6个(当然也得看你的数据的原始字段个数)

MySQL—【加餐1】高效查询方法相关推荐

  1. mysql递归查询 缓存_MySQL-递归查询方法解析

    MySQL-递归查询方法解析,兄弟连教育(www.lampbrother.net)帮大家做了个简单的整理:有需要的朋友可以参考下哈. 首先 表结构和数据 CREATE TABLE `class` ( ...

  2. MySQL大数据量分页查询方法及其优化

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:收藏了!7 个开源的 Spring Boot 前后端分离优质项目个人原创+1博客:点击前往,查看更多 链接:ht ...

  3. 千锋重庆Java学习之MySQL大数据量分页查询方法及其优化

    方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...

  4. mysql 字段中有括号的查询方法

    查询字段中带中括号 尝试的方法有: select [新车价格含税(万)]from rereche_item_a select `[新车价格含税(万)]`from rereche_item_a sele ...

  5. mysql动态多条件模糊查询方法

    1.对于我个前端,写mysql真的掉头发. 2.很简单,只要你学习mysql之后就会指导IF语句和Like语句,便可以啦. 3. 首先我们知道下面两条语句的效果是一样的. select * from ...

  6. mysql一样的查询在我本地很快但是线上很慢_MySQL大数据量分页查询方法及其优化...

    MySQL大数据量分页查询方法及其优化 ---方法1: 直接使用数据库提供的SQL语句 ---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N ---适 ...

  7. MySQL 和 Oracle 大数据量分页查询方法及其优化

    MySQL大数据量分页查询方法及其优化 ---方法1: 直接使用数据库提供的SQL语句 ---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N ---适 ...

  8. mysql表格查询方法

    笛卡尔积 交叉连接(CROSS JOIN):有两种,显式的和隐式的2种,一般用来返回连接表的笛卡尔积. 笛卡尔积(Cartesian product)是指两个集合 X 和 Y 的乘积. 例如,有 A ...

  9. 千万级别数据查询优化_MySQL大数据量分页查询方法及其优化

    MySQL大数据量分页查询方法及其优化 ---方法1: 直接使用数据库提供的SQL语句 ---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N ---适 ...

最新文章

  1. 功能基因多样性研究概述
  2. 软件测试2019:第三次作业
  3. 黑客发飙!智能汽车不太安全你还敢开?
  4. Application provided invalid, non monotonically increasing dts to muxer in stream 0: -92233720368547
  5. Algorithm Course Review(7.1)
  6. 几种搜索引擎算法的研究
  7. java rest 序列化_http请求/restful/序列化反序列化/JSON
  8. python 发送邮件不显示附件_python无法通过电子邮件发送附件文件
  9. 利用Diferencia和Java微服务进行分接比较测试
  10. linux调用信号处理程序后返回,如何在Linux上执行异步信号处理程序?
  11. 【weblogic】部署jfinal编写的应用
  12. apache 设置session超时时间_深入分析 Session 和 Cookie,看这篇就对了
  13. ele-plus包的安装和使用
  14. 脚本(js)控制页面输入
  15. 泰森中国宣布与阿里云达成战略合作
  16. easyui datagrid加载本地数据和网络数据
  17. XAMPP报错:mysqli::real_connect(): (HY000/1045): Access denied for user ‘pma‘@‘localhost‘
  18. 俺重装系统后一些小配置(给自己备忘)
  19. 单片机智能密码锁c语言程序,基于单片机控制的密码锁设计(含电路图及源程序)...
  20. 如何批量删除 Word 文档的只读密码?

热门文章

  1. wps 模拟分析 规划求解_Excel数据分析两大利器,趋势预测与规划求解
  2. word 流水号 自动增加_以自动组卷软件为例浅谈Python自动化办公
  3. php大牛额城战笔记,PHP语言大牛开发笔记(8)——MySQL数据库基础回顾[2]
  4. 一个空的C++类中有什么
  5. python 控件显示时间_设置tkinter标签以显示倒计时时间
  6. uniapp在低版本android,uni-app离线打包Android平台注意事项
  7. 文本基线怎样去掉_ICML 2020 | 基于类别描述的文本分类模型
  8. mysql jdbc 协议_JDBC-MySql
  9. oracle触发器修改同一张表,oracle触发器中对同一张表进行更新再查询时,需加自制事务...
  10. c 语言 结构体的引用