今天楼主给你们列一下关于数据库几个常见问题的要点,若是你们对其中的问题感兴趣,能够自行扩展研究。前端
UNION和UNION ALL关键字都是将两个结果集合并为一个。mysql
UNION在进行表连接后会筛选掉重复的记录,因此在表连接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。sql
而UNION ALL只是简单的将两个结果合并后就返回。数据库
因为UNION须要排序去重,因此 UNION ALL 的效率比 UNION 好不少。segmentfault
0 rows affected
,能够解释为没有返回结果。相同点
缓存
YYYY-MM-DD HH:MM:SS
。不一样点
性能
TIMESTAMP
1970-01-01 08:00:01~2038-01-19 11:14:07
。DATETIME
1000-10-01 00:00:00~9999-12-31 23:59:59
。两个或更多个列上的索引被称做联合索引,联合索引又叫复合索引。mysql索引
减小开销
:建一个联合索引(col1,col2,col3),实际至关于建了(col1),(col1,col2),(col1,col2,col3)三个索引。减小磁盘空间的开销。覆盖索引
:对联合索引(col1,col2,col3),若是有以下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那么MySQL能够直接经过遍历索引取得数据,而无需回表,这减小了不少的随机io操做。覆盖索引是主要的提高性能的优化手段之一。效率高
:索引列越多,经过索引筛选出的数据越少。有1000W条数据的表,有以下sql select from table where col1=1 and col2=2 and col3=3
,假设假设每一个条件能够筛选出10%的数据,若是只有单值索引,那么经过该索引能筛选出1000W*10%=100w
条数据,而后再回表从100w条数据中找到符合col2=2 and col3= 3的数据,而后再排序,再分页;若是是联合索引,经过索引筛选出1000w*10%*10%*10%=1w
,效率获得明显提高。a = 1 and b = 2 and c > 3 and d = 4
若是创建(a,b,c,d)
顺序的索引,d是用不到索引的,若是创建(a,b,d,c)
的索引则均可以用到,a,b,d的顺序能够任意调整。a = 1 and b = 2 and c = 3
创建(a,b,c)
索引能够任意顺序,mysql的查询优化器会帮你优化成索引能够识别的形式。前缀索引就是对文本的前几个字符(具体是几个字符在建立索引时指定)建立索引,这样建立起来的索引更小。可是MySQL不能在ORDER BY或GROUP BY中使用前缀索引,也不能把它们用做覆盖索引。优化
建立前缀索引的语法:spa
ALTER TABLE table_name ADD
KEY(column_name(prefix_length))
复制代码
简单的说:
主索引的区别
:InnoDB的数据文件自己就是索引文件。而MyISAM的索引和数据是分开的。
辅助索引的区别
:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。
InnoDB中数据记录自己被存于主索引(B+树)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,所以每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的结点和位置,若是页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页。
若是使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引结点的后续位置,当一页写满,就会自动开辟一个新的页,这样就会造成一个紧凑的索引结构,近似顺序填满。因为每次插入时也不须要移动已有数据,所以效率很高,也不会增长不少开销在维护索引上。
若是使用非自增主键,因为每次插入主键的值近似于随机,所以每次新纪录都要被插入到现有索引页的中间某个位置,此时MySQL不得不为了将新记录查到合适位置而移动元素,甚至目标页可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增长了不少开销,同时频繁的移动、分页操做形成了大量的碎片,获得了不够紧凑的索引结构,后续不得不经过 OPTIMIZE TABLE
来重建表并优化填充页面。
简单的说:
索引树只能定位到某一页,每一页内的插入仍是须要经过比较、移动插入的。因此有序主键能够提高插入效率。
int占多少个字节,已是固定的了,长度表明了显示的最大宽度。若是不够会用0在左边填充,但必须搭配zerofill使用。也就是说,int的长度并不影响数据的存储精度,长度只和显示有关。
Table
:
Non_unique
:
0
:该索引不含重复值。1
:该索引可含有重复值。Key_name
:
PRIMARY
。Seq_in_index
:
idx_a_b_c (
a,
b,
c)
,则a的Seq_in_index
=1,b=2,c=3。Column_name
:
Collation
:
Cardinality
:
ANALYZE TABLE
(INNODB) 或者 myisamchk -a
(MyISAM)更新该值。Sub_part
:
NULL
。Null
:
YES
:该列容许NULL值。''
:该列不容许NULL值。Index_type
:
LIKE问题
:like 以通配符开头 ('%abc...'),mysql索引失效会变成全表扫描的操做。
LIKE
,LIKE
条件是 type = range
级别%xxx%
:全表扫描%xxx
:全表扫描xxx%
:range解决办法
:
ALL
变为INDEX
,为啥呢?覆盖索引以后就能使用使用索引进行全表扫描。这里要注意一下,使用符合索引的时候,命中一个字段就能够,不用所有命中。SELECT * FROM ttl_product_info ORDER BY id LIMIT N,M
。其中 LIMIT N,M
存在的问题最大:取出N+M行,丢弃前N行,返回 N ~ N+M
行的记录,若是N值很是大,效率极差(表记录1500w,N=10000000,M=30 须要9秒)。SELECT id FROM ttl_product_info WHERE id > N LIMIT M
,id 列是索引列,id > N
属于 range
级别,效率天然高,而后从位置开始取30条记录,效率极高(表记录1500w,N=10000000,M=30,须要0.9毫秒)。为了保持文章结构的完整性,这里强行加上一段总结。。。
参考文章: