本文简单讲述了PHP数据库编程之MySQL优化策略。分享给你们供你们参考,具体以下:php
前些天看到一篇文章说到PHP的瓶颈不少状况下不在PHP自身,而在于数据库。咱们都知道,PHP开发中,数据的增删改查是核心。为了提高PHP的运行效率,程序员不光须要写出逻辑清晰,效率很高的代码,还要能对query语句进行优化。虽然咱们对数据库的读取写入速度上倒是无能为力,但在一些数据库类扩展像memcache、mongodb、redis这样的数据存储服务器的帮助下,PHP也能达到更快的存取速度,因此了解学习这些扩展也是很是必要,这一篇先说一下MySQL常见的优化策略。mysql
点此加入个人企鹅群laravel
一、SQL语句中的关键词最好用大写来书写,第一易于区分关键词和操做对象,第二,SQL语句在执行时,MySQL会将其转换为大写,手动写大写能增长查询效率(虽然很小)。程序员
二、若是咱们们经对数据库中的数据行进行增删,那么会出现数据ID过大的状况,用ALTER TABLE tablename AUTO_INCREMENT=N
,使自增ID从N开始计数。正则表达式
三、对int类型添加 ZEROFILL
属性能够对数据进行自动补0redis
四、导入大量数据时最好先删除索引再插入数据,再加入索引,否则,mysql会花费大量时间在更新索引上。算法
五、建立数据库书写sql语句时 ,咱们能够在IDE里建立一个后缀为.sql的文件,IDE会识别sql语法,更易于书写。更重要的是,若是你的数据库丢失了,你还能够找到这个文件,在当前目录下使用/path/mysql -uusername -ppassword databasename < filename.sql
来执行整个文件的sql语句(注意-u和-p后紧跟用户名密码,无空格)。sql
一、数据库设计符合第三范式,为了查询方即可以有必定的数据冗余。mongodb
二、选择数据类型优先级 int > date,time > enum,char>varchar > blob,选择数据类型时,能够考虑替换,如ip地址能够用ip2long()函数转换为unsign int型来进行存储。shell
三、对于char(n)类型,在数据完整的状况下尽可能较小的的n值。
四、在建表时用partition命令对单个表分区能够大大提高查询效率,MySQL支持RANGE,LIST,HASH,KEY分区类型,其中以RANGE最为经常使用,分区方式为:
CREATE TABLE tablename{ }ENGINE innodb/myisam CHARSET utf8 //选择数据库引擎和编码 PARTITION BY RANGE/LIST(column),//按范围和预约义列表进行分区 PARTITION partname VALUES LESS THAN /IN(n),//命名分区并详细限定分区的范围
五、选择数据库引擎时要注意innodb 和 myisam的区别。
存储结构:MyISAM在磁盘上存储成三个文件。而InnoDB全部的表都保存在同一个数据文件中,通常为2GB
事务支持:MyISAM不提供事务支持。InnoDB提供事务支持事务。
表锁差别:MyISAM只支持表级锁。InnoDB支持事务和行级锁。
全文索引:MyISAM支持 FULLTEXT类型的全文索引(不适用中文,因此要用sphinx全文索引引擎)。InnoDB不支持。
表的具体行数:MyISAM保存有表的总行数,查询count(*)很快。InnoDB没有保存表的总行数,须要从新计算。
外键:MyISAM不支持。InnoDB支持
一、innodb是聚簇索引,存储索引时必须有主键,若是没有指定,引擎会自动生成一个隐藏的主键,生成一个主索引,索引内存放的是主键的物理地址,数据靠主键存放,每次使用索引时要先找到主索引,而后找到主索引下的数据。
优势经过主键查找特别快,缺点是次级索引会变慢,由于须要先经过次级索引(次级索引里是主索引的位置。)找到主索引,而后经过主索引找数据。而且若是主键无规律,插入新值时须要移动较多数据块,会影响效率,因此要尽可能使用有规律递增的int型作主键。还有由于数据紧跟着主键放,因此若是数据中有数据量特别大的列(text/blob),innodb查询时会跳过不少数据块,也会致使慢。
二、myisam的索引各个索引都相同统一指向磁盘上各个行的地址,都是轻量级的指针数据。缺点是各个索引的创建不是经过主键,查询没有聚簇索引查找主键快。但其由于存储的是地址,因此在插入新值时比较方面移动改变。
三、进行多条件查询时,对多条件分别创建索引时,执行sql查询时,MySQL只会选择一个最贴近的索引来使用,因此若是须要多条件查询,要创建联合索引,即便会形成数据冗余。
联合索引的BTREE创建方法:对第一个条件创建索引,在第一个索引的BTREE区域对第二个条件创建索引,以此类推,因此,在使用索引时,不用第一个条件用第二个条件也不会用到联合索引。使用索引时要条件要有顺序,有序列的使用。
四、索引长度对查询也有很大影响,咱们应该尽可能创建短的索引长度,咱们可使用查询列
SELECT COUNT(DISTINCT LEFT(column)) / COUNT(*) FROM tablename 来测试对column列创建索引时选取不一样的长度,索引的覆盖率有多大,咱们选择一下接近饱和的n个长度来创建索引
ALTER TABLE tablename ADD INDEX (column(n)); 来对某一列的前n个字符创建索引。若前n个字符相同,咱们甚至能够对字符串进行反转存储,而后创建索引。
五、对于常常修改致使的索引碎片的维护方式:ALTER TABLE tablename ENGINE oldengine;即再次应用一下表存储引擎,使其自动维护;也能够用 OPTIMIZE tablename 命令来进行维护。
数据库操做尽可能少查询,有查询时尽可能不在数据库层面上进行数据操做,而是返回到PHP脚本中操做数据,减轻数据库压力。
一旦发现有数据库性能问题,要及时解决,通常用慢查询日志记录查询很"慢"的语句,用EXPLAIN分析查询和索引使用状况,用PROFILE分析语句执行时的具体资源消耗。
一、在my.ini或my.cnf的[mysqld]下添加
slow_query_log_file=/path //设置日志存储路径
long_query_time=n //设置若是语句执行时间达到n秒,就会被记录下来
二、而后在MySQL里设置SET slow_query_log='ON'来开启慢查询。
三、记录下日志后,咱们用/bin/目录下的mysqldumpslow filename来查看日志,其经常使用参数以下:
-g pattern 使用正则表达式
-t n返回前n条数据
-s c/t/l/r 以记录次数/时间/查询时间/返回记录数来排序
使用方法,在要执行的查询语句前面加EXPLAIN
EXPLAIN SELECT * FROM user;
获得形以下图的结果:
下面是对每一项的解释:
id 查询语句的id,简单查询无心义,多重查询时能够看出执行查询的顺序
select-type 执行的查询语句的类型,对应多重查询,有simple/primary/union等。
tabel 查询语句查询的数据表
type 得到数据的类型 常见的类型效率从高到低为 null>const>eq_ref>ref>range>index>all
possible-keys:可能使用到的索引
key 使用到的索引
key_len索引长度
ref 使用哪一个列与索引一块儿从表中选择。
rows 查找到数据要扫描的大概行数,可看出索引的优劣
extra 常见的有
using filesort 查询到数据后进行文件排序,较慢,须要优化索引
using where 读取整行数据后进行判断过滤,是否符合where条件
using index 索引覆盖,即在牵引中已经有这存储了目标数据,直接读取索引,很快。
用SELECT @@frofiling来查看PROFILE的开启状态。
若是未开启,用SET profiling=1来开启。
开启以后,再执行查询语句,MySQL会自动记录profile信息。
应用show profiles查看全部的sql信息,结果为 Query_ID Duration Query三列结果,分别是查询ID,用时和所用的sql语句。
咱们可使用
SHOW PFROFILE [type[,type]][FOR QUREY Query_ID][Limit rwo_count [OFFSET offset]]
type常见有ALL(所有) BLOCK IO(显示IO相关开销) CPU(CPU开销) MEMORY(内存开销)等
一、master将改变记录到二进制日志中,slave将master的二进制拷贝到它的中继日志中,从新将数据返回到它本身的数据中,达到复制主服务器数据的目的。
主从复制能够用做:数据库负载均衡、数据库备份、读写分离等功能。
二、配置主服务器master
修改my.ini/my.conf [mysqld] log-bin=mysql-bin //启用二进制日志 server-id=102 //服务器惟一ID
三、配置从服务器slave
log-bin=mysql-bin //启用二进制日志 server-id=226 //服务器惟一ID
四、在主服务器上受权从服务器
GRANT REPLICATION SLAVE ON *.* to 'slavename'@'IP' identified by 'root'
五、在从服务器上使用
change master to master_host="masterip", master_user="masteruser", master_password="masterpasswd";
六、而后使用start slave命令开始进行主从复制。
不要忘记在每次修改配置后重启服务器,而后能够在主从服务器上用show master/slave status查看主/从状态。
实现数据库的读写分离要依赖MySQL的中间件,如mysql_proxy,atlas等。经过配置这些中间件来对主从服务器进行读写分离,使从服务器承担被读取的责任,从而减轻主服务器的负担。
在数据库中数据表中的数据量很是庞大的时候,不管是索引仍是缓存等压力都很大,对数据库进行sharding,使之分别以多个数据库服务器或多个表存储,以减轻查询压力。
方式有垂直切分、水平切分和联合切分。
垂直切分:在数据表很是多的时候,把数据库中关系紧密(如同一模块,常常链接查询)的表切分出来分别放到不一样的主从server上。
水平切分:在表很少,而表里的数据量很是大的时候,为了加快查询,能够用哈希等算法,将一个数据表分为几个,分别放到不一样的服务器上,加快查询。水平切分和数据表分区的区别在于其存储介质上的不一样。
联合切分:更多的状况是数据表和表中的数据量都很是大,则要进行联合切分,即同时进行垂直和水平分表,将数据库切分为一个分布式的矩阵来存储。
这些数据库的优化方式,每一种拿出来均可以写做一篇文章,可谓是博大精深,了解并记忆了这些方式,能够在有须要的时候进行有目的的选择优化,达到数据库效率的高效。
好了各位,以上就是这篇文章的所有内容了,能看到这里的人呀,都是人才。以前说过,PHP方面的技术点不少,也是由于太多了,实在是写不过来,写过来了你们也不会看的太多,因此我这里把它整理成了PDF和文档,若是有须要的能够
更多学习内容能够访问【对标大厂】精品PHP架构师教程目录大全,只要你能看完保证薪资上升一个台阶(持续更新)
以上内容但愿帮助到你们,不少PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提高,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货须要的能够免费分享给你们,须要的能够加入个人 PHP技术交流群