Mysql建表与索引使用规范详解

1、Mysql建表、索引

  1. MySQL建表,字段需设置为非空,需设置字段默认值。
  2. MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL。
  3. MySQL建表,若是字段等价于外键,应在该字段加索引。
  4.  MySQL建表,不一样表之间的相同属性值的字段,列类型,类型长度,是否非空,是否默认值,需保持一致,不然没法正确使用索引进行关联对比。
  5. MySQL使用时,一条SQL语句只能使用一个表的一个索引。全部的字段类型均可以索引,多列索引的属性最多15个。
  6. 若是能够在多个索引中进行选择,MySQL一般使用找到最少行的索引,索引惟一值最高的索引。
  7.  创建索引index(part1,part2,part3),至关于创建了 index(part1),index(part1,part2)和index(part1,part2,part3)三个索引。
  8. MySQL针对like语法必须以下格式才使用索引:     SELECT * FROM t1 WHERE key_col LIKE 'ab%' ;
  9. SELECT COUNT(*) 语法在没有where条件的语句中执行效率没有SELECT COUNT(col_name)快,可是在有where条件的语句中执行效率要快。
  10. 在where条件中多个and的条件中,必须都是一个多列索引的key_part属性并且必须包含key_part1。各自单一索引的话,只使用遍历最少行的那个索引。
  11. 在where条件中多个or的条件中,每个条件,都必须是一个有效索引。
  12. ORDER BY 后面的条件必须是同一索引的属性,排序顺序必须一致(好比都是升序或都是降序)。
  13. 全部GROUP BY列引用同一索引的属性,而且索引必须是按顺序保存其关键字的。
  14. JOIN 索引,全部匹配ON和where的字段应创建合适的索引。
  15. 对智能的扫描全表使用FORCE INDEX告知MySQL,使用索引效率更高。
  16. 按期ANALYZE TABLE tbl_name为扫描的表更新关键字分布 。
  17. 按期使用慢日志检查语句,执行explain,分析可能改进的索引。
  18. 条件容许的话,设置较大的key_buffer_size和query_cache_size的值(全局参数),和sort_buffer_size的值(session变量,建议不要超过4M)。

2、索引的类型

使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构, 与必须搜索表中的全部行相比,索引会帮助您更快地得到该信息。
索引提供指向存储在表的指定列中的数据值的指针,而后根据您指定的排序顺序对这些指针排序。数据库使用索引的方式与您使用书籍中的索引的方式很类似:它搜索索引以找到特定值,而后顺指针找到包含该值的行。mysql

做为通用规则,只有当常常查询索引列中的数据时,才须要在表上建立索引。索引占用磁盘空间,而且下降添加、删除和更新行的速度。sql

若是常常同时搜索两列或多列或按两列或多列排序时,索引也颇有帮助。例如,若是常常在同一查询中为姓和名两列设置判据,那么在这两列上建立多列索引将颇有意义。数据库

索引类型
根据数据库的功能,能够在数据库设计器中建立三种索引:惟一索引、主键索引和汇集索引。session

a.惟一索引
惟一索引是不容许其中任何两行具备相同索引值的索引
b.主键索引
数据库表常常有一列或列组合,其值惟一标识表中的每一行,该列称为表的主键。
在数据库关系图中为表定义主键将自动建立主键索引,主键索引是惟一索引的特定类型。该索引要求主键中的每一个值都惟一。数据库设计

c.汇集索引
在汇集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个汇集索引。
若是某索引不是汇集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非汇集索引相比,汇集索引一般提供更快的数据访问速度。函数

键选择原则:性能

1) 键设计4 原则优化

为关联字段建立外键。
全部的键都必须惟一。
避免使用复合键。
外键老是关联惟一的键字段。
2) 使用系统生成的主键url

设计数据库的时候采用系统生成的键做为主键,那么实际控制了数据库的索引完整性。这样,数据库和非人工机制就有效地控制了对存储数据中每一行的访问。采用系统生成键做为主键还有一个优势:当拥有一致的键结构时,找到逻辑缺陷很容易。spa

3) 不要用用户的键(不让主键具备可更新性)

在肯定采用什么字段做为表的键的时候,可必定要当心用户将要编辑的字段。一般的状况下不要选择用户可编辑的字段做为键。

4) 可选键有时可作主键

把可选键进一步用作主键,能够拥有创建强大索引的能力。

3、数据库索引的使用规则

索引使用原则:
索引是从数据库中获取数据的最高效方式之一。95%的数据库性能问题均可以采用索引技术获得解决。

逻辑主键使用惟一的成组索引,对系统键(做为存储过程)采用惟一的非成组索引,对任何外键列采用非成组索引。考虑数据库的空间有多大,表如何进行访问,还有这些访问是否主要用做读写。
大多数数据库都索引自动建立的主键字段,可是可别忘了索引外键,它们也是常用的键,好比运行查询显示主表和全部关联表的某条记录就用得上。
不要索引memo/note 字段,不要索引大型字段(有不少字符),这样做会让索引占用太多的存储空间。
不要索引经常使用的小型表
不要为小型数据表设置任何键,假如它们常常有插入和删除操做就更别这样做了。对这些插入和删除操做的索引维护可能比扫描表空间消耗更多的时间。

应该建索引的字段:1.常常做为查询条件的字段2.用于联接的列(主健/外健)3.在SQL语句中常常进行GROUP BY、ORDER BY的字段;四、在常常存取的多个列上创建复合索引,但要注意复合索引的创建顺序要按照使用的频度来肯定

应该少建或者不建索引的字段有:1.表记录太少,2.常常须要插入,删除,修改的表,3.表中数据重复且分布平均的字段

一些SQL的写法会限制索引的使用:1.where子句中若是使用in、or、like、!= <>,均会致使索引不能正常使用,将"<>"换成">and<";将"is not null "换成">=chr(0)";2.使用函数时,该列就不能使用索引。3.比较不匹配数据类型时,该索引将会被忽略。

一些SQL语句优化的写法:1.若是from是双表的查询时,大表放在前面,小表放在后面(基础表)。最后面的表是基础表。(只在基于规则的优化器中有效)2.若是三表查询时,选择交叉表(intersection table)做为基础表.(只在基于规则的优化器中有效)3.写where条件时,有索引字段的判断在前,其它字段的判断在后;若是where条件中用到复合索引,按照索引列在复合索引中出现的顺序来依次写where条件;4.查询数量较大时,使用表链接代替IN,EXISTS,NOT IN,NOT EXISTS等。5.ORACLE采用自下而上的顺序解析WHERE子句,那些能够过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

注:缺省状况下创建的是非簇集索引,但在如下状况下最好考虑簇集索引,如:含有有限数目(不是不多)惟一的列;进行大范围的查询;充分的利用索引能够减小表扫描I/0的次数,有效的避免对整表的搜索。固然合理的索引要创建在对各类查询的分析和预测中,也取决于DBA的所设计的数据库结构。索引的字段的类型也需重点考虑,字符字段索引就比数字字段索引慢得多。

备注
主键的命名采用以下规则:
主键名用pk_开头,后面跟该主键所在的表名。主键名长度不能超过30个字符。若是过长,可对表名进行缩写。缩写规则同表名的缩写规则。主键名用小写的英文单词来表示。
 
外键的命名采用以下规则:
外键名用fk_开头,后面跟该外键所在的表名和对应的主表名(不含t_)。子表名和父表名本身用下划线(_)分隔。外键名长度不能超过30个字符。若是过长,可对表名进行缩写。缩写规则同表名的缩写规则。外键名用小写的英文单词来表示。

索引的命名采用以下规则:
1)索引名用小写的英文字母和数字表示。索引名的长度不能超过30个字符。
2)主键对应的索引和主键同名。
3)惟一性索引用uni_开头,后面跟表名。通常性索引用ind_开头,后面跟表名。
4)若是索引长度过长,可对表名进行缩写。缩写规则同表名的缩写规则

index 相关语法
例:
CREATE INDEX log_url ON logaudit_log(url);
show index from logaudit_log
drop index log_request_time on logaudit_log
sql执行效率检测 mysql explain
explain显示了mysql如何使用索引来处理select语句以及链接表。能够帮助选择更好的索引和写出更优化的查询语句。
使用方法,在select语句前加上explain就能够了:
如:explain select surname,first_name form a,b where a.id=b.id
分析结果形式以下:
table |  type | possible_keys | key | key_len  | ref | rows | Extra
EXPLAIN列的解释:
table
显示这一行的数据是关于哪张表的
type
这是重要的列,显示链接使用了何种类型。从最好到最差的链接类型为const、eq_reg、ref、range、indexhe和ALL
possible_keys
显示可能应用在这张表中的索引。若是为空,没有可能的索引。能够为相关的域从WHERE语句中选择一个合适的语句
key
实际使用的索引。若是为NULL,则没有使用索引。不多的状况下,MYSQL会选择优化不足的索引。这种状况下,能够在SELECT语句中使用USE
INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引
key_len
使用的索引的长度。在不损失精确性的状况下,长度越短越好
ref
显示索引的哪一列被使用了,若是可能的话,是一个常数
rows
MYSQL认为必须检查的用来返回请求数据的行数
Extra
关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里能够看到的坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢
extra列返回的描述的意义
Distinct
一旦MYSQL找到了与行相联合匹配的行,就再也不搜索了
Not exists
MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,
就再也不搜索了
Range checked for each
Record(index map:#)
没有找到理想的索引,所以对于从前面表中来的每个行组合,MYSQL检查使用哪一个索引,并用它来从表中返回行。这是使用索引的最慢的链接之一
Using filesort
看到这个的时候,查询就须要优化了。MYSQL须要进行额外的步骤来发现如何对返回的行排序。它根据链接类型以及存储排序键值和匹配条件的所有行的行指针来排序所有行
Using index
列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的所有的请求列都是同一个索引的部分的时候
Using temporary
看到这个的时候,查询须要优化了。这里,MYSQL须要建立一个临时表来存储结果,这一般发生在对不一样的列集进行ORDER BY上,而不是GROUP BY上
Where used
使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。若是不想返回表中的所有行,而且链接类型ALL或index,这就会发生,或者是查询有问题
不一样链接类型的解释(按照效率高低的顺序排序)
system
表只有一行:system表。这是const链接类型的特殊状况
const
表中的一个记录的最大值可以匹配这个查询(索引能够是主键或唯一索引)。由于只有一行,这个值实际就是常数,由于MYSQL先读这个值而后把它当作常数来对待
eq_ref
在链接中,MYSQL在查询时,从前面的表中,对每个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或唯一键的所有时使用
ref
这个链接类型只有在查询使用了不是唯一或主键的键或者是这些类型的部分(好比,利用最左边前缀)时发生。对于以前的表的每个行联合,所有记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好
range
这个链接类型使用索引返回一个范围中的行,好比使用>或
FAQ
1
表中包含 10 万条记录,有一个 datetime 类型的字段。
取数据的语句:
SELECT * FROM my_table WHERE created_at < '2010-01-20';
用 EXPLAIN 检查,发现 type 是 ALL, key 是 NULL,根本没用上索引。
能够肯定的是,created_at 字段设定索引了。
什么缘由呢?
用 SELECT COUNT(*) 看了一下符合 WHERE 条件的记录总数,竟然是 6W 多条!!
难怪不用索引,这时用索引毫无心义,就好像 10 万条记录的用户表,有个性别字段,不是男就是女,在这种字段设置索引是错误的决定。
稍微改造一下上述语句:
SELECT * FROM my_table WHERE created_at BETWEEN '2009-12-06' AND '2010-01-20';
这回问题解决!
符合条件的记录只有几百条,EXPLAIN 的 type 是 range,key 是 created_at,Extra 是 Using where 。
本身总结个准则,索引的目的就是尽可能缩小结果集,这样才能作到快速查询。

6万条记录符合条件,已经超出总记录数的一半,这时索引已经没有意义了,所以 MySQL 放弃使用索引。 这与设置 gender 字段,并加上索引的状况类似,当你要把全部男性记录都选取出来,符合条件的记录数约占总数的一半,MySQL 一样不会使用这个索引。 惟一值越多的字段,使用索引的效果越好。 设置联合索引时,惟一值越多的,越应该放在“左侧”。  

相关文章
相关标签/搜索