mysql优化

一,表的设计符合3NF,慢查询sql优化
    1.1NF数据原子性,关系型数据库(例:mysql,sql server)都符合
    2.2NF表中的记录是唯一的,通常设计一个主键来实现
    3.3NF表中数据不要冗余,表的数据能够推导出来,就不应该单独一个字段
    4.慢查询sql优化
        #global:mysql启动开始的select情况[session|global]
        show global status like 'com_select';
        #显示慢查询次数
        show global status like 'slow_queries';
        #显示慢查询时间
        show variables like 'long_query_time';
        #设置慢查询时间
        set long_query_time=1;
        #配置my.ini慢查询日志文件
        slow-query-log-file=/www/server/data/mysql-slow.log
        #重启mysql开启慢查询
        mysqld --safe-mode --slow-query-log
        #通过explain 分析mysql如何执行sql语句
二,适当的索引(主键索引/唯一索引/全文索引/普通索引/外键索引/组合索引)
    
    1.主键索引:必须为主键字段创建一个索引,这个索引就是所谓的”主索引”。主索引与唯一索引的唯一区别是:前者在定义时使用的关键字是 PRIMARY而不是UNIQUE。
        #添加
            #创建表时添加主键索引
            create table aa(id int unsigned primary key auto_increment);
            #创建后添加主键索引
            create table aa(id int);
            alter table aa add primary key(id);
    2.唯一索引:它与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
        #添加
            #创建表时添加唯一索引
            create table aa(id int unsigned unique);
            #创建后添加唯一索引
            create table aa(id int);
            alter table aa add unique(id);

        
        #查询
    3.全文索引:文本字段上的普通索引只能加快对出现在字段内容最前面的字符串(也就是字段内容开头的字符)进行检索操作。如果字段里存放的是由几个、甚至是多个单词构成
        的较大段文字,普通索引就没什么作用了。这种检索往往以LIKE %word%的形式出现,这对MySQL来说很复杂,如果需要处理的数据量很大,响应时间就会很长。
        这类场合正是全文索引(full-text index)可以大显身手的地方。在生成这种类型的索引时,MySQL将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数
        据记录。全文索引即可以随数据表一同创建,也可以等日后有必要时再使用下面这条命令添加:
        ALTER TABLE tablename ADD FULLTEXT(column1, column2)
        有了全文索引,就可以用SELECT查询命令去检索那些包含着一个或多个给定单词的数据记录了。下面是这类查询命令的基本语法:
        SELECT * FROM tablename
        WHERE MATCH(column1, column2) AGAINST(‘word1′, ‘word2′, ‘word3′)
        上面这条命令将把column1和column2字段里有word1、word2和word3的数据记录全部查询出来。
        注解:InnoDB数据表不支持全文索引。新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,从MySQL 5.7开始支持中文全文索引,所以具体信息要随时关注官网
        #添加
            #创建表时添加全文索引
                CREATE TABLE article (
                  id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
                  title VARCHAR(200),
                  body TEXT,
                  FULLTEXT(title, body)
                  ) TYPE=MYISAM;
            #alter table方式添加
                 ALTER TABLE `student` ADD FULLTEXT INDEX 索引名称  (`name`) #ft_stu_name是索引名,可以随便起
                   或者:ALTER TABLE `student` ADD FULLTEXT 索引名称  (`name`);
               #create index方式添加
                   CREATE FULLTEXT INDEX 索引名称 ON `student` (`name`);
                也可以在创建索引的时候指定索引的长度:
                CREATE FULLTEXT INDEX 索引名称 ON `student` (`name`(20));
        #使用方法:全文索引不能使用like "%fulltext%"
            select * from student where match(name) agains('full');
    4.普通索引:普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHERE column = …)或排序条件(ORDER BY column)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
        #添加
        create table aa(id int unsigned);
        create index id on aa(id);
    
    5.组合索引:索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引。这种索引的特点是MySQL可以有选择地使用一个这样的索引。如果查询操作只需要用到columnA数据列上的一个索引,
        就可以使 用组合索引INDEX(columnA, columnB)。不过,这种用法仅适用于在组合索引中排列在前的数据列组合。比如说,INDEX(A, B, C)可以当做A或(A, B)的索引来使用,但不能当做B、C或(B, C)的索引来使用。

        #添加
        alert table aa add INDEX `sindex` (`a`,`b`,`c`);
    6.外键索引:一个表的主键索引是另一个表的字段
            #创建表时添加全文索引
                CREATE TABLE article (
                  id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
                  tid VARCHAR(200)
                  FOREIGN KEY (tid) REFERENCES student (tid)
                  ) TYPE=INNODB;
            #alter table方式添加
                 ALTER TABLE article ADD FOREIGN KEY ids(tid) REFERENCES student (tid);
    7.查询索引
        desc aa;#不能显示索引名
        show index from aa;#查询详细信息
        show keys from aa; #查询详细信息
    8.删除索引
            #直接使用 drop index
                DROP INDEX 索引名称 ON student;
            #使用 alter table的方式
                ALTER TABLE student DROP INDEX 索引名称;
    9.index_type索引类型btree和hash的区别
        在MySQL中,大多数索引(如 PRIMARY KEY,UNIQUE,INDEX和FULLTEXT)都是在BTREE中存储,但使用memory引擎可以选择BTREE索引或者HASH索引,两种不同类型的索引各自有其不同的使用范围。
        Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
        可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢?任何事物都是有两面性的,Hash 索引也一样,虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。
        (1)Hash 索引仅仅能满足”=”,”IN”和”<=>”查询,不能使用范围查询。
            由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
        (2)Hash 索引无法被用来避免数据的排序操作。
            由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
        (3)Hash 索引不能利用部分索引键查询。
            对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
        (4)Hash 索引在任何时候都不能避免表扫描。
            前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
        (5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
            对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
    10.索引的长度
        在为CHAR和VARCHAR类型的数据列定义索引时,可以把索引的长度限制为一个给定的字符个数(这个数字必须小于这个字段所允许的最大字符个数)。这
        么做的好处是可以生成一个尺寸比较小、检索速度却比较快的索引文件。在绝大多数应用里,数据库中的字符串数据大都以各种各样的名字为主,把索引的长度设置
        为10~15个字符已经足以把搜索范围缩小到很少的几条数据记录了。
        在为BLOB和TEXT类型的数据列创建索引时,必须对索引的长度做出限制;MySQL所允许的最大索引长度是255个字符。
    11.添加索引的条件(在where中经常使用,字段内容重复率较低,字段内容变化频率较低)
        #较频繁作为查询条件的字段应该创建索引,例如手机号码
        #唯一性太差的字段不适合单独创建索引,例如男女
        #更新非常频繁的字段不适合添加索引,例如金额
        #不作为查询条件的字段不应创建索引
    12.explain查看sql语句执行情况
        id:1                 #查询序列号
        select_type:SIMPLE     #查询类型
        table:dept             #查询的表名
        partitions:NULL     #表分区
        type:ALL             #扫瞄的方式,all全表扫描
        possible_keys:NULL     #可能使用到的索引
        key:NULL             #实际使用的索引
        key_len:NULL         #
        ref:NULL             #
        rows:10             #该sql语句扫描了多少行,可能得到记录数
        Extra:Using where     #sql语句的额外信息,比如排序方式...

        explain详解
        https://www.cnblogs.com/galengao/p/5780958.html
    13.索引使用注意事项
        a.对于使用like的查询,查询如果是'%aaa' 不会使用到索引,'aaa%'会使用到索引。
        b.如果条件中有or,那么使用的所有字段都必须建立索引。
        d.如果列类型是字符串,那么条件中的数据要使用引号 '数据' ,否则不会使用索引。添加数据时字符串也必须使用引号'数据'。
        c.如果mysql估计使用全表扫描要比使用索引快,则不会使用索引。
    14.查看索引的使用情况
        show status like 'Handler_read%';
        Handler_read_key:这个值越高越好,越高表示使用索引查询到的次数
        Handler_read_rnd_next:这个值越高,说明查询低效。
    15.mysql小技巧
        a.大批量导入数据时可以先禁用索引,减少创建索引的时间,提高数据导入效率
        b.group by语句默认分组时,还会排序,可能会降低速度,添加order by null可以防止排序。
        c.尽量使用join查询,因为使用join不需要在内存中创建临时表
        d.选择合适的存储引擎
            Myisam:如果一张表对事物要求不高,同事是以查询和添加为主的表,应该考虑使用mysiam,如BBS中的发帖表,回复表。
            innodb:对事物要求高,保存的数据都是重要数据,应该考虑使用innodb,比如订单表,账号表。
            Memory:数据变化非常频繁,不需要入库,同时又频繁的查询和修改,应该考虑使用mempry,比如信息配置,字段类型不支持text,重启mysql数据丢失
        e.尽量使用定点数来存储数值,以保证数据的精确性
        f.myisam如果经常删除修改记录,需要定期执行optimize table aa;对表进行碎片整理,否则会出现删除修改的数据无变化
        g.备份数据库 mysqldump -uroot -p123456 数据库名称 > 文件路径,备份某些表 mysqldump -uroot -p123456 数据库名称 表名称 > 文件路径,恢复数据 source 文件路径
        h.海量数据分页查询优化,order by使用索引字段。 select * from testsea where title like "左%" order by tid limit 90000,10;
三,分表
    1.水平分割
        分表维度:程序自定义,例:user0,user1,user2,根据用户的id%3查对应的表,一般需要一个辅助表来记录分表的用户id
        分页查询:建立辅助表存储总记录数
    2.垂直分割
四,主从复制
    1.读写分离
    2.多主,热备
五,存储过程
六,存储引擎的区别
                             Myisam       innodb       bdb     memory     archive
    *批量插入速度       高              低            高           高           非常高
    *事物安全                              支持         支持     
    *全文索引              支持        5.6.4<
    *锁机制                  表锁        行锁          页锁       表锁         行锁
    存储限制               无             64TB         无           有            无
    B数索引                支持           支持         支持      支持
    哈希索引                                 支持                      支持
    集群索引                                 支持
    数据缓存                                 支持                      支持
    索引缓存               支持           支持                      支持
    数据可压缩            支持                                                      支持
    空间使用               低                高              低       N/A        非常低
    内存使用               低                高              低       中等        低
    支持外键                                 支持

七,表分区
八,搜索引擎Elasticsearch,sphinx
九,mysql原理
十,mysql自动优化设计
    1.自动统计各表的sql语句
    2.自动分析慢查询语句
    3.根据sql语句自动优化

高并发数据库设计
1.获取表相关信息
    a.查询user辅助表(memory引擎)对应的主从服务器,表不存在时自动创建新表
    b.使用固定算法计算出对应的主从服务器,表不存在时自动创建新表
2.查询对应的主从服务器
    user1->独立主从服务器
    user2->独立主从服务器
    user3->独立主从服务器
问题:
    1.分表+分库能使用union联合查询吗
    2.不能使用union联合查询,分页排序怎么处理

你可能感兴趣的:(mysql)