作者回复: 这是一个很好的问题,关于ORDER BY字段是否增加索引:
在MySQL中,支持两种排序方式:FileSort和Index排序。Index排序的效率更高,
Index排序:索引可以保证数据的有序性,因此不需要再进行排序。
FileSort排序:一般在内存中进行排序,占用CPU较多。如果待排结果较大,会产生临时文件I/O到磁盘进行排序,效率较低。
所以使用ORDER BY子句时,应该尽量使用Index排序,避免使用FileSort排序。
当然具体优化器是否采用索引进行排序,你可以使用explain来进行执行计划的查看。
优化建议:
1、SQL中,可以在WHERE子句和ORDER BY子句中使用索引,目的是在WHERE子句中避免全表扫描,ORDER BY子句避免使用FileSort排序。
当然,某些情况下全表扫描,或者FileSort排序不一定比索引慢。但总的来说,我们还是要避免,以提高查询效率。
一般情况下,优化器会帮我们进行更好的选择,当然我们也需要建立合理的索引。
2、尽量Using Index完成ORDER BY排序。
如果WHERE和ORDER BY相同列就使用单索引列;如果不同使用联合索引。
3、无法Using Index时,对FileSort方式进行调优。
作者回复: 多谢提问,这句话我说的比较省略。想表达的意思是,如果你使用了WHERE子句,对于某个字段进行了条件筛选,那么这个字段你可以通过建立索引的方式进行SQL优化。
因为我们在进行SQL优化的时候,应该尽量避免全表扫描。所以当我们使用WHERE子句对某个字段进行了条件筛选时,如果我们没有对这个字段建立索引,就会进入到全表扫描,因此可以考虑对这个字段建立索引。
当然你也需要注意 索引是否会失效。因此除了考虑建立字段索引以外,你还需要考虑:
1、不要在WHERE子句后面对字段做函数处理,同时也避免对索引字段进行数据类型转换
2、避免在索引字段上使用<>,!=,以及对字段进行NULL判断(包括 IS NULL, IS NOT NULL)
3、在索引字段后,慎用IN和NOT IN,如果是连续的数值,可以考虑用BETWEEN进行替换
因为在WHERE子句中,如果对索引字段进行了函数处理,或者使用了<>,!=或NULL判断等,都会造成索引失效。
作者回复: 在MySQL8.0版本之前,当我们ALTER TABLE时系统崩溃了,则会遗留.frm,.ibd文件。而在8.0版本之后,MySQL默认的InnoDB存储引擎实现了原子DDL。原子 DDL 操作写入了内部隐藏的系统表,即mysql.innodb_ddl_log中,也就是说明在DDL执行过程中如果出现了失败,是可以回滚的。
需要说明的是:DDL如果正常运行结束后,ddl_log中的相应日志也会被删除。如果这中间崩溃了,重启时会根据事务是否提交了来判断是做redo,还是undo DLL操作。
作者回复: 可以考虑:
1、建立索引
2、使用函数来替代LIKE,
如果是MySQL的话:可以考虑locate, position, instr, find_in_set
如果是SQL Server,可以考虑charindex, patindex
作者回复: 对的 解释正确
作者回复: 哈哈 太乙真人太太 这个解释的好。也就是在第一个字符之后能匹配上“太”字。
作者回复: 感谢提问,不是随机的5条。最简单的方式,你可以多重复几次,然后看下结果有没有变化。你会发现,每次运行的结果都是一样的,因此不是随机的。
如果想实现随机5条数据,可以采用下面的方式:
SELECT name,role_main,role_assist, RAND() as r FROM heros WHERE role_assist IS NOT NULL ORDER BY r LIMIT 5
作者回复: 解释的很好,关于为什么使用DATE函数的说明可以看下这个
作者回复: 正确,同时采用了列别名的方式。
作者回复: 正确
作者回复: 解释的很好,最后一个SQL查询也正确
作者回复: 就是在数据库中对某个字段创建索引,索引是一种查找方式,方便后续按照索引进行条件查找
作者回复: _%太% 匹配东皇太一,不会匹配到太乙真人。因为_相当于至少要匹配一个字符,所以除了第一个字符以外,需要有“太”字,也就是东皇太一。
作者回复: 是的,在ORACLE中可以使用TO_CHAR, TO_DATE做转换:
TO_CHAR 把日期或数字转换为字符串
TO_DATE 把字符串转换为日期类型
同时在MySQL中也有类似的函数
DATE_FORMAT(date,'%Y-%m-%d') 对应 TO_CHAR
STR_TO_DATE(date,'%Y-%m-%d') 对应 TO_DATE
比如 SELECT DATE_FORMAT(NOW(),'%m-%d-%Y') AS result
SELECT STR_TO_DATE('2017-01-01 00:10:10','%Y-%m-%d %H:%i:%s') AS result
作者回复: Good Job
作者回复: 加油~
作者回复: 正确,结果也显示出来了。