当前位置: 首页 > 科技观察

想了解PHP数据库编程的MySQL优化策略概述?进来我告诉你

时间:2023-03-16 17:23:33 科技观察

本文简单介绍PHP数据库编程的MySQL优化策略。分享给大家,供大家参考,如下:前几天看到一篇文章说PHP的瓶颈很多时候不在PHP本身,而在数据库。我们都知道在PHP开发中,数据的增删改查是核心。为了提高PHP的运行效率,程序员不仅要写出逻辑清晰高效的代码,还要能够优化查询语句。虽然对于数据库的读写速度我们无能为力,但是借助于一些数据库扩展如memcache、mongodb、redis等数据存储服务器,PHP也可以达到更快的访问速度,所以了解和学习这些扩展也是非常必要的。本文先说说MySQL常见的优化策略。MySQL的几个小技巧1、SQL语句中的关键字最好大写。首先,容易区分关键字和操作对象。第二,SQL语句执行的时候,MySQL会把它转成大写,手动写入大写。可以提高查询效率(虽然很小)。2、如果我们在数据库中增加或删除数据行,数据ID会太大。使用ALTERTABLEtablenameAUTO_INCREMENT=N使自增ID从N开始计数。3.给int类型加上ZEROFILL属性可以自动填充数据。04.导入大量数据时,最好先删除索引,再插入数据,再添加索引,否则mysql会花费大量时间更新索引。5、在创建数据库和编写sql语句的时候,我们可以在IDE中创建一个后缀为.sql的文件,IDE会识别sql语法,写起来更方便。更重要的是,如果你的数据库丢失了,你仍然可以找到这个文件,在当前目录下使用/path/mysql-uusername-ppassworddatabasenamedate,time>enum,char>varchar>blob。选择数据类型时,可以考虑替换。比如可以将ip地址用ip2long()函数转换成unsignint类型进行存储。3、对于char(n)类型,在数据完整的情况下,n值越小越好。4、在建表时,使用分区命令对单表进行分区,可以大大提高查询效率。MySQL支持RANGE、LIST、HASH、KEY分区类型,其中以RANGE最为常用,分区方式为:1.CREATETABLEtablename{2.}ENGINEinnodb/myisamCHARSETutf8//选择数据库引擎和编码3.PARTITIONBYRANGE/LIST(column),//按范围和预定义列表进行分区4.PARTITIONpartnameVALUESLESSTHAN/IN(n),//命名分区并详细限制分区的范围5.注意innodb和myisam在选择数据库引擎时的区别。存储结构:MyISAM在磁盘上存储三个文件。所有InnoDB表都存储在同一个数据文件中,一般2GB事务支持:MyISAM不提供事务支持。InnoDB提供事务支持事务。表锁的区别:MyISAM只支持表级锁。InnoDB支持事务和行级锁。全文索引:MyISAM支持FULLTEXT类型的全文索引(中文不适用,所以使用sphinx全文索引引擎)。InnoDB不支持它。表的具体行数:MyISAM保存表的总行数,查询count(*)很快。InnoDB不保存表的总行数,需要重新计算。外键:MyISAM不支持。InnoDB支持索引优化1.InnoDB是聚集索引。存储索引时必须有主键。如果不指定,引擎会自动生成隐藏主键并生成主索引。主键的物理地址存储在索引中。数据依赖于主键存储。每次使用索引都要先找到主索引,然后再找到主索引下的数据。优点是通过主键查找非常快。缺点是二级索引会比较慢,因为需要先通过二级索引找到一级索引(二级索引就是一级索引所在的位置。),然后通过一级索引找到数据。而如果主键是不规则的,插入新值时需要移动更多的数据块,会影响效率,所以尽量使用有规律递增的int类型作为主键。还有,因为数据是放在主键旁边的,如果数据中有数据量特别大的列(text/blob),InnoDB在查询的时候会跳过很多数据块,也会导致变慢。2、myisam的索引都是以同样的方式指向磁盘上每一行的地址,都是轻量级的指针数据。缺点是各个索引的建立不是通过主键,查询速度不如聚簇索引找主键。但是因为它存储地址,所以它会在插入新值时移动和更改。3、在进行多条件查询时,当对多个条件分别建立索引时,MySQL在执行SQL查询时只会选择最接近的索引来使用,所以如果需要进行多条件查询,则必须建立联合索引,即使这样会造成数据冗余保留。联合索引的BTREE创建方法:第一个条件创建索引,第二个条件在第一个索引的BTREE区域建立索引,以此类推,所以在使用索引的时候,不要使用第一个条件和使用第二个条件将不会使用联合索引。在使用索引的时候,条件必须是有序的,并且是顺序使用的。4.索引长度对查询也有很大的影响。我们应该尽量建立一个较短的索引长度。我们可以使用查询列SELECTCOUNT(DISTINCTLEFT(column))/COUNT(*)FROMtablename来测试在该列上建索引时选择column不同长度,索引的覆盖范围有多大,我们选择n个长度接近饱和建立索引ALTERTABLEtablenameADDINDEX(column(n));为列的前n个字符建立索引。如果前n个字符相同,我们甚至可以对字符串进行逆向存储,然后建立索引。5、对于频繁修改导致的索引碎片的维护方法:ALTERTABLEtablenameENGINEoldengine;即再次应用表存储引擎,使其自动维护;您也可以使用OPTIMIZEtablename命令进行维护。在数据查询方面,优化数据库操作,尽量减少查询。有查询时,尽量不要在数据库层面进行数据操作,而是返回PHP脚本操作数据,减少数据库压力。一旦发现数据库性能问题,应及时解决。一般慢查询日志用来记录“慢”的查询语句,EXPLAIN用来分析查询和索引的使用情况,PROFILE用来分析语句执行时具体的资源消耗情况。慢查询日志:1.在my.ini或my.cnf中[mysqld]下添加slow_query_log_file=/path//设置日志存放路径long_query_time=n//设置如果语句执行时间达到n秒,则记录2,然后在MySQL中设置SETslow_query_log='ON',开启慢查询。3、记录日志后,我们使用/bin/目录下的mysqldumpslow文件名查看日志。常用参数如下:-gpattern使用正则表达式-tn返回前n条数据-sc/t/l/r记录次数/time/查询时间/返回记录数对EXPLAIN语句使用方法,在要执行的查询语句前加上EXPLAIN1.EXPLAINSELECT*FROMuser;得到结果如下图:每一项解释如下:id查询语句的id,简单的查询是没有意义的,在多查询的情况下可以看到执行查询的顺序select-type要执行的查询语句的类型,对应多个查询,有simple/primary/union等tabel查询语句查询的数据表类型获取数据的类型常见类型效率从高到低是null>const>eq_ref>ref>range>index>allpossible-keys:可能使用的索引键indexkey_lenindexlengthref要使用的列以及要从表中选择的索引。rows找到数据大概要扫描的行数,可以看到索引extra的优缺点。常见的是查询完数据后使用filesort对文件进行排序,速度较慢。需要使用where优化索引读取整行数据,然后判断过滤是否满足where条件使用索引索引覆盖,即目标数据已经存在traction中,直接索引阅读,这将非常快。PROFILE使用SELECT@@frofiling查看PROFILE的打开状态。如果未启用,请使用SETprofiling=1启用它。启用后,执行查询语句,MySQL会自动记录profile信息。使用showprofiles查看所有sql信息,结果为Query_IDDurationQuery三列结果,分别是查询ID、时间和使用的sql语句。我们可以使用1.SHOWPFROFILE[type[,type]][FORQUREYQuery_ID][Limitrwo_count[OFFSEToffset]]type一般有ALL(全部)BLOCKIO(显示IO相关开销)CPU(CPU开销)MEMORY(内存开销)等大规模存储优化数据库主从复制和读写分离1.master会在binarylog中记录变化,slave会把master的binary复制到它的relaylog中并返回数据到自己的数据,达到复制主服务器数据的目的。主从复制可用于:数据库负载均衡、数据库备份、读写分离等功能。2、配置主服务器master修改my.ini/my.conf[mysqld]log-bin=mysql-bin//启用二进制日志server-id=102//服务器唯一ID3,配置从服务器slavelog-bin=mysql-bin//启用二进制日志server-id=226//服务器的唯一ID4,在主服务器上授权从服务器1.GRANTREPLICATIONSLAVEON*.*to'slavename'@'IP'identifiedby'root'5、在slave服务器上使用changemastertomaster_host="masterip",master_user="masteruser",master_password="masterpasswd";6、然后使用startslave命令启动主从复制。每次修改配置不要忘记重启服务器,然后可以在主从服务器上使用showmaster/slavestatus查看主从状态。实现数据库的读写分离依赖于MySQL中间件,如mysql_proxy、atlas等,通过配置这些中间件在主从服务器之间进行读写分离,从服务器承担被读的责任,从而减少主服务器的负担。当数据库中数据表的数据量非常大时,数据库的分片无论是索引还是缓存都会承受很大的压力。数据库被分片,存储在多个数据库服务器或多个表中,以减少查询压力。有纵向拆分、横向拆分和联合拆分。垂直拆分:当数据表很多时,将数据库中关系密切(如同一模块,经常连接查询)的表拆分出来,放在不同的主从服务器上。水平切分:当表不多,表中数据量很大时,为了加快查询速度,可以使用hash等算法,将一张数据表分成若干张,分别放在不同的服务器上加快查询速度。水平分片和数据表分区的区别在于存储介质的不同。联合切分:更多情况下,数据表和表中的数据量非常大,需要联合切分,即同时进行垂直和水平的表切分,将数据库分成一个用于存储的分布式矩阵。这些数据库优化方法每一种都可以用来写一篇文章。可谓博大精深。了解并记住这些方法后,我们可以在必要时进行有目的的选择和优化,以达到较高的数据库效率。