MYSQL数据类型和where条件

本文介绍了MySQL中常用的字符型、整型、浮点型及日期时间数据类型,并提供了WHERE条件判断的应用实例,如关系运算、逻辑运算、BETWEEN...AND...、IN、LIKE、EXISTS子查询等。

MySQL中常见的数据类型

一、字符型
① CHAR(N):固定N个字符长度的字符串,如果长度不够自动空格补齐; N的范围 0~255
② VARCHAR(N): 存储可变长度的字符串,最常用
③ TEXT: 存储可变长度的字符串,(常用于发布文章等大段内容)
④ TINYTEXT:0~2^8-1 *10
⑤ MEDIUMTEXT: 0~2^24-1 *10^3;
⑥ LONGTEXT: 0~2^32-1 * 10^4;
二、整形:
① TINYINT: 无符号0~2^8-1 有符号 -2^7 ~ 2^7-1;
② SMALLINT: 无符号0~2^16-1 有符号 -2^15 ~ 2^15-1;
③ MEDIUMINT: 无符号0~2^24-1 有符号 -2^23 ~ 2^23-1;
④ INT: 无符号0~2^32-1 有符号 -2^31 ~ 2^31-1; 最常用
⑤ BIGINT: 无符号0~2^64-1 有符号 -2^63 ~ 2^63-1;
三、浮点型
① FLOAT: 可以精确到小数点后7位有效数字
② DOUBLE: 可以精确到小数点后15-16位有效数字
四、日期时间数据类型
注意:由于时间存储使用字符串或者时间戳存储,所以数据库中几乎不用日期类型
① DATE(expr):存储日期和时间数据
② `TIMESTAMP`(expr) :比DATE更准确;

[常用where条件判断]    关系运算>,<,=,>=,<=

逻辑运算 NOT AND OR
ISNUL(字段)检测是否为空
SELECT*FROM tb1 WHERE ISNULL(age);所有年龄为空的用户
 BETWEEN..AND..介于俩个值之间
 SELECT*FROM tb1 WHERE ISNULL age BETWEEN 10 AND 14;相当于 age>=10 AND age<=14;
 in 在某些值之间的数据
 SELECT*FROM tb1 WHERE id in(1,2,3,4,5);
 like 相似匹配
 ①相似匹配时使用%表示任意字符个数(0到多个);
 SELECT*FROM tb1 WHERE username LIKE "张%";用张开头 "%张";用张结尾;"%张%",任意位置包含张
 相似匹配时,使用_表示字符的个数;
 SELECT*FROM tb1 WHERE username LIKE "_二%";第二个字是二的;
 7.EXISTS 子查询语句:如果子查询语句与返回数据>=1行,则EXISTS返回true;否则返回false;
 如果tb2返回至少一行数据,则条件成立
8.ALL (子查询),子查询返回的数据,需要全部满足,才能
用户名不能等于,子查询返回用户名列表中的任意一个
9.ANY(子查询) 子查询返回的数据,满足其中一个,即可成立
 用户名 等于 子查询返回用户名列表中的任意一个;
 删除表中数据

转载于:https://www.cnblogs.com/dsmf/p/7078413.html

<think>在MySQL中,索引的使用对于查询性能至关重要。当查询语句中包含WHERE条件ORDERBY子句时,索引的设计可以同时优化过滤排序操作。###1.**索引的基本概念**索引是一种数据结构,用于快速查找数据库表中的特定行。常见的索引类型有B-Tree索引(InnoDB默认)、哈希索引、全文索引等。###2.**WHERE条件与索引**在WHERE子句中使用的列如果建立了索引,MySQL可以利用索引快速定位到符合条件的行。###3.**ORDERBY与索引**如果ORDERBY子句中的列有索引,MySQL可以利用索引的有序性避免额外的排序操作(即filesort)。###4.**联合索引(CompositeIndex)**当WHERE条件ORDERBY涉及多个列时,联合索引可能非常有效。但要注意联合索引中列的顺序。####4.1最佳实践:将WHERE条件中的列放在联合索引的前面,然后是ORDERBY中的列。例如:```sqlSELECT*FROMtableWHEREcondition1=?ANDcondition2=?ORDERBYsort1,sort2;```可以创建索引:```sqlCREATEINDEXidx_condition_sortONtable(condition1,condition2,sort1,sort2);```####4.2特殊情况:如果WHERE条件使用的是范围查询(如>、<、BETWEEN),那么ORDERBY的列可能无法使用索引。因为范围查询后面的列无法利用索引的有序性。###5.**覆盖索引(CoveringIndex)**如果索引包含了查询中所有需要的数据(即要查询的列都在索引中),则MySQL可以直接从索引中获取数据而不需要回表,这可以极大地提高性能。###6.**示例**假设有表`orders`:```sqlCREATETABLEorders(idINTPRIMARYKEY,user_idINT,order_dateDATE,amountDECIMAL(10,2),statusVARCHAR(20));```####场景1:同时使用WHEREORDERBY查询:获取某个用户的所有订单,并按订单日期降序排列。```sqlSELECT*FROMordersWHEREuser_id=123ORDERBYorder_dateDESC;```创建索引:```sqlCREATEINDEXidx_user_order_dateONorders(user_id,order_dateDESC);```这个索引可以同时用于过滤`user_id`排序`order_date`。####场景2:范围查询与排序查询:获取某个用户在某个日期之后的所有订单,并按订单金额排序。```sqlSELECT*FROMordersWHEREuser_id=123ANDorder_date>'2020-01-01'ORDERBYamount;```此时,如果创建索引`(user_id,order_date,amount)`,由于`order_date`使用了范围查询,所以排序字段`amount`无法利用索引的有序性。因此,MySQL可能会对满足条件的行进行额外的排序操作。替代方案:如果查询经常执行,可以考虑改变索引顺序,但注意WHERE条件中的等值查询应放在范围查询之前。然而,在这个例子中,等值查询只有`user_id`,范围查询是`order_date`,所以无法将`amount`放在范围查询之前。因此,可能需要接受这个限制,或者尝试使用覆盖索引来减少IO。###7.**EXPLAIN分析**使用`EXPLAIN`命令可以查看MySQL的执行计划,判断是否使用了索引,以及是否避免了额外的排序。例如:```sqlEXPLAINSELECT*FROMordersWHEREuser_id=123ORDERBYorder_dateDESC;```在输出中,注意:-`type`:表示访问类型,如ref、range等。-`key`:使用的索引。-`Extra`:若包含`Usingfilesort`,则表示进行了额外的排序,应尽量避免。###8.**总结**-尽量让WHERE条件ORDERBY使用相同的索引。-在联合索引中,将等值查询的列放在前面,范围查询的列放在后面,最后是排序的列。-注意范围查询可能导致后续排序列无法使用索引。-使用覆盖索引避免回表。-使用EXPLAIN分析查询。§§相关问题§§:1.什么是覆盖索引?请举例说明。2.在MySQL中,如何查看一个查询是否使用了索引?3.联合索引中列的顺序为什么重要?请举例说明。4.什么情况下ORDERBY无法使用索引?</think>### MySQL索引中WHERE条件ORDER BY字段的优化策略 在MySQL查询优化中,**WHERE条件ORDER BY字段的索引设计**直接影响查询性能。以下是核心原则解决方案: --- #### **1. 索引设计的最佳实践** **原则**:优先满足WHERE条件的过滤,再考虑ORDER BY的排序 **推荐方案**:创建**联合索引**,顺序为 `WHERE字段在前,ORDER BY字段在后` **示例场景**: ```sql SELECT * FROM orders WHERE user_id = 100 ORDER BY create_time DESC; ``` **优化方案**: ```sql -- 创建联合索引(WHERE字段在前,ORDER BY字段在后) CREATE INDEX idx_user_create ON orders(user_id, create_time); ``` **为什么有效**: - `user_id` 作为等值查询条件可快速过滤数据 - `create_time` 利用索引有序性避免额外排序(`Using filesort`) --- #### **2. 范围查询的特殊处理** **问题**:当WHERE包含范围查询(如 `>`、`<`、`BETWEEN`)时,ORDER BY可能无法使用索引排序 **示例**: ```sql SELECT * FROM orders WHERE price > 100 -- 范围查询 ORDER BY create_time; -- 排序字段 ``` **解决方案**: - **方案1**:调整索引顺序(需结合业务) ```sql CREATE INDEX idx_price_create ON orders(price, create_time); ``` *注意:仅对特定范围值有效,可能仍需部分排序* - **方案2**:覆盖索引优化 ```sql CREATE INDEX idx_cover ON orders(price, create_time, id); ``` - **方案3**:拆分查询(分页场景适用) ```sql SELECT * FROM orders WHERE id IN ( SELECT id FROM orders WHERE price > 100 ORDER BY create_time LIMIT 20 ); ``` --- #### **3. 多字段排序优化** **场景**:同时按多个字段排序 ```sql SELECT * FROM products WHERE category = 'electronics' ORDER BY price ASC, stock DESC; ``` **索引设计**: ```sql -- 联合索引(WHERE条件 + 所有排序字段) CREATE INDEX idx_cat_price_stock ON products(category, price, stock); ``` **关键点**: - ORDER BY字段顺序必须与索引一致(如 `price ASC, stock DESC`) - 混合ASC/DESC时需指定索引排序方向(MySQL 8.0+): ```sql CREATE INDEX idx_cat_price_stock ON products(category, price ASC, stock DESC); ``` --- #### **4. 索引失效的常见陷阱** **失效场景**: 1. **WHERE与ORDER BY字段无交集** ```sql WHERE a = 1 ORDER BY c -- 索引 (a,b) 无法覆盖c的排序 ``` 2. **ORDER BY包含非索引字段** 3. **使用函数或表达式** ```sql ORDER BY YEAR(create_time) -- 导致索引失效 ``` 4. **联合索引顺序错误** ```sql INDEX (b, a) -- 但查询是 WHERE a=1 ORDER BY b ``` **解决方案**: - 使用`EXPLAIN`检查`Extra`列是否出现 `Using filesort` - 确保ORDER BY字段是索引的最左前缀或与WHERE连续 --- #### **5. 性能对比验证** 通过`EXPLAIN`分析执行计划: ```sql EXPLAIN SELECT * FROM orders WHERE user_id = 100 ORDER BY create_time; ``` **理想结果**: - `type: ref` - `key: idx_user_create` - `Extra: Using index condition`(无`Using filesort`) --- ### 总结核心原则 1. **等值查询优先**:WHERE中的等值条件(`=`)应放在索引最左侧 2. **排序字段连续**:ORDER BY字段需紧接WHERE字段,且顺序一致 3. **避免范围查询中断**:范围查询后的排序字段通常无法用索引优化 4. **覆盖索引是终极武器**:通过`INCLUDE`或联合索引覆盖查询字段
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值