python SQL--mysql调优笔记(一)

mysql的索引类型

主要内容:

  1. 索引使用或是创建需要注意

索引类型:PRIMARY, INDEX,UNIQUE,FULLTEXT,SPAIAL。
区别以及各适用场合:

举个例子来说,比如做某商场一个会员卡的系统。
这个系统有一个会员表
有下列字段:
会员编号 INT
会员姓名 VARCHAR(10)
会员身份证号码 VARCHAR(36)
会员电话 VARCHAR(15)
会员住址 VARCHAR(50)
会员备注信息 TEXT

那么这个 "会员编号" 作为主键,使用 PRIMARY
"会员姓名" 如果要建索引的话,那么就是普通的 INDEX
"会员身份证号码" 如果要建索引的话,那么可以选择 UNIQUE (唯一的,不允许重复)
"会员备注信息" 如果需要建索引的话,可以选择 FULLTEXT,全文搜索。

不过 FULLTEXT 用于搜索很长一篇文章的时候,效果最好。
用在比较短的文本,如果就一两行字的,普通的 INDEX 也可以。
-------------------------------------------------------------------------------------
普通索引:这是最基本的索引类型,而且它没有唯一性之类的限制。

唯一性索引:这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。

MYSQL主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。

全文索引 (适合在进行模糊查询‘like’的时候使用):MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索
引的索引类型为FULLTEXT。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命
令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者
CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。

索引的创建:

  • 说明:
    UNIQUE:可选。表示索引为唯一性索引。
    FULLTEXT:可选。表示索引为全文索引。
    SPATIAL:可选。表示索引为空间索引。
    INDEX和KEY:用于指定字段为索引,两者选择其中之一就可以了,作用是 一样的。
    索引名:可选。给创建的索引取一个新名称。
    字段名1:指定索引对应的字段的名称,该字段必须是前面定义好的字段。
    长度:可选。指索引的长度,必须是字符串类型才可以使用。
    ASC:可选。表示升序排列。
    DESC:可选。表示降序排列。

  • 查看已创建的索引:
    show index from 表名;

注:这里只为示例如何创建索引,其他的合理性之类的先放一边。

  • 建表时创建:
建表时创建:
CREATE TABLE 表名(

字段名 数据类型 [完整性约束条件],
       ……,
       ……,
       ……,

[UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY

[索引名](字段名1 [(长度)] [ASC | DESC]) [USING 索引方法]

);

----------------------例子----------------------
CREATE TABLE projectfile (
	id INT AUTO_INCREMENT COMMENT '附件id',
	fileuploadercode VARCHAR(128) COMMENT '附件上传者code',
	projectid INT COMMENT '项目id;此列受project表中的id列约束',
	
	-- 主键本身也是一种索引(注:也可以在上面的创建字段时使该字段主键自增)
        PRIMARY KEY (id),
	-- 主外键约束(注:project表中的id字段约束了此表中的projectid字段)
	FOREIGN KEY (projectid) REFERENCES project (id),
	-- 给projectid字段创建了唯一索引(注:也可以在上面的创建字段时使用unique来创建唯一索引)
	UNIQUE INDEX (projectid),
	-- 给fileuploadercode字段创建普通索引
	INDEX (fileuploadercode)
	-- 指定使用INNODB存储引擎(该引擎支持事务)、utf8字符编码
)
  • 建表后创建:
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL]  INDEX | KEY  [索引名] (字段名1 [(长度)] 
[ASC | DESC]) [USING 索引方法];

或

CREATE  [UNIQUE | FULLTEXT | SPATIAL]  INDEX  索引名 ON  表名(字段名) [USING 索引方法];

----------------------例子----------------------
-- 假设建表时fileuploadercode字段没创建索引(注:同一个字段可以创建多个索引)
-- 给projectfile表中的fileuploadercode创建索引

ALTER TABLE projectfile ADD UNIQUE INDEX (fileuploadercode);

create unique index "索引名称" on projectfile (fileuploadercode)
  • SQL执行效率检查
explain + 查询SQL:用于评估 SQL执行效率,根据参考信息可以进行SQL优化

----------------------例子----------------------
EXPLAIN SELECT * FROM projectfile ;

优化经验

主要内容:

  1. 查询语句where 子句使用的时候优化或者需要注意的
  2. like语句使用时候需要注意
  3. in语句的代替语句

假设会员表有一百万会员量。也就是1000000,id是主键

  • 对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by 涉及的列上创建索引。
    因为:索引对查询的速度有着至关重要的影响。
  • 并不是所有索引对查询都有效,sql是根据表中数据进行查询优化的,当索引name(索引字段)有大量重复数据的时候,sql查询可能不会去利用索引。如一表中字段 sex、male、female 几乎各一半。那么即使在sex上创建了索引对查询效率也起不了多大作用。
  • 索引创建需注意:并非索引创建越多越好。索引固然可以提高相应的查询效率,但是同样会降低insert以及update的效率。因为在insert或是update的时候有可能会重建索引或是修改索引。所以索引怎样创建需要慎重考虑,视情况而定。一个表中所以数量最好不要超过6个。若太多,则需要考虑一些不常用的列上创建索引是否有必要。
  • 用exists 代替 in是一个很好的选择。
  • 当只需要一条数据时使用limit 1。若已经知道结果只有一条的时候,尽量加一个limit 1 ,这样一来,mysql在查询到一条数据之后,会立即停止搜索,这会带来性能上的提升。
  • 如果不进行以下操作,引擎可能放弃使用索引,进而进行全表扫描的情况:
    1. 尽量避免在where字句中对字段进行null值的判断(列值尽量设置非空)。
      例如:select id from projectfile where projectid is null 。可以将num是这个字段设置默认值0.确保表中没有null值,然后在进行查询。
      sql如下:select id from projectfile where projectid =0;
    2. 应尽量避免在where子句中使用!=或者是<>操作符号。
    3. 应尽量避免在where子句中使用or来连接条件。可以使用 union 或者是 union all代替。
    4. in 和 not in 慎用,可以使用between …and.来代替。
    5. 需要like的可以使用全文检索
    6. where子句参数使用时候需注意。sql只会在运行时才会解析局部变量。但优化程序不能将访问计划的选择推迟到运行时;必须在编译时候进行选择。然而,如果在编译时建立访问计划,变量的值还是未知大,因而无法作为索引选择输入项。
      例如以下SQL将会进行全表扫描:
      select id from user where id= @id;
      知道ID就是主键,是索引,所以可以改为强制查询使用索引:
      select id from user force (index(索引名称)) where id = @id;
    7. 尽量避免在where子句中对字段进行表达式操作。
    8. 尽量避免在where子句中对字段进行函数操作。
    9. 不要在where子句中的"="左边进行函数、算术运算或是使用其他表达式运算,否则系统可能无法正确使用索引。
    10. 复合索引查询注意:在使用索引字段作为条件时候,如果该索引是复合索引,那么必须使用该索引中的第一个字段作为条件时候才能保证系统使用该所以,否则该索引将不会被使用,并且应尽可能的让字段顺序和索引顺序一致。
    11. 尽可能的使用not null。除非有一个很特别的原因要去使用null值,应该总让字段保持为not null。

如有侵权,请联系我!!!

你可能感兴趣的:(数据库,优化)