mysql数据库优化汇总
高速查询缓存可以通过MySQL服务器上的查询来实现,后台数据库引擎是提高性能的最有效的方法之一,当同一个查询执行多次时,如果从缓存中提取结果,则速度非常快。
但是主要的问题是它很容易隐藏,以至于我们的大多数程序员都会忽略它,在一些处理任务中,我们实际上可以停止查询缓存工作。
复制代码代码如下所示:
缓存不工作
r = mysql_query(选择用户名从用户那里signup_date(CURDATE)> = );
缓存工程 /查询!
今天美元=日期(当前);
r = mysql_query(选择用户名从用户那里signup_date > = $今天);
缓存不工作
r = mysql_query(选择用户名从用户那里signup_date(CURDATE)> = );
缓存工程 /查询!
今天美元=日期(当前);
r = mysql_query(选择用户名从用户那里signup_date > = $今天);
2。使您的选择查询更清楚地解释
使用解释关键字是另一种MySQL优化技术。它可以让您知道MySQL正在做什么样的查询操作,这可以帮助您找到瓶颈,并显示查询或表结构的问题所在。
解释查询的结果可以告诉你这些索引是如何被引用的,表是如何被扫描和排序的,等等。
要实现SELECT查询(最好是一个更复杂的查询),请添加关键字来解释它。在这里我们可以使用phpMyAdmin,他将表中的结果告诉你。例如,如果我忘了要将列添加到索引时我正在执行的加入,能帮我找到问题的解释。
添加索引后group_id场
三.得到限制1的唯一行
有时,当你不得不寻找一张表时,你知道你只需要看到一行,你可以去一个非常独特的记录,或者只是检查任何存在的记录,它们都满足你的WHERE子句。
在这种情况下,添加一个限制1将使查询更有效,因此数据库引擎发现只有1会停止扫描,而不是扫描整个表或索引。
复制代码代码如下所示:
我有任何用户来自亚拉巴马州吗
不要这样做:
r = mysql_query(SELECT * FROM用户状态= 'alabama);
如果(mysql_num_rows(r)> 0){
…
}
好得多:
r = mysql_query(选择1从用户那里'alabama'limit状态= 1 );
如果(mysql_num_rows(r)> 0){
…
}
4中的检索字段。指数
索引不仅是主键或唯一键。如果要搜索表中的任何列,则应始终指向索引。
5。确保连接的索引是相同的类型。
如果应用程序中有多个连接查询,则需要确保链接的列在两侧表上索引,这将影响MySQL如何优化内部连接操作。
此外,所添加的列必须是相同的类型。例如,如果添加一个十进制列并在另一个表中添加int列,MySQL将不能使用至少一个指示符。甚至字符编码也必须是String类型。
复制代码代码如下所示:
对于我所在州的公司
r = mysql_query(选择company_name用户
左连接公司(users.state =公司。状态)
在users.id = $ user_id );
应将状态列编入索引
它们都应该是相同类型和字符编码。
或者MySQL可能会做全表扫描。
6。不要使用命令()
这是许多新手程序员会陷入的陷阱,你可能不知不觉地陷入了一种可怕的平静。
如果你真的需要给你的结果是随机的,有很多更好的方法。这是真的,这就需要编写更多的代码,但它避免了性能瓶颈。问题是,MySQL可能执行RAND()表中每一行的命令,这将消耗处理器的处理能力,然后返回你一行。
复制代码代码如下所示:
不要这样做:
r = mysql_query(选择由兰德用户订单用户名()限1);
好得多:
r = mysql_query(select count(*)从用户);
美元D = mysql_fetch_row(r);
兰德= mt_rand美元(0,$ { 0 } - 1);
r = mysql_query(选择用户限制为1兰特,用户名);
7。尽量避免选择*命令
您从表中读取的数据越多,查询就变慢了。他增加了磁盘需要操作的时间,或者是与数据库服务器和Web服务器分离的时间。您将经历非常长的网络延迟,仅仅因为数据不需要在服务器之间传输。
总是指定你需要的列,这是一个很好的习惯。
复制代码代码如下所示:
不喜欢
r = mysql_query(选择*从用户那里user_id = 1 );
美元D = mysql_fetch_assoc(r);
回声欢迎{ $ { 'username} };
/更好:
r = mysql_query(选择用户名从用户那里user_id = 1 );
美元D = mysql_fetch_assoc(r);
回声欢迎{ $ { 'username} };
较大的结果集之间的差异更为显著。
8。从过程分析中获得建议()
程序分析()可以从MySQL的列结构和表中的实际数据分析中给您一些建议。
9。准备好的语句
准备好的报表可以帮助您从性能优化和安全性两个方面帮助您。
编写的语句可以通过过滤已经绑定的默认变量来给应用程序提供有效的保护,防止SQL注入攻击。当然,您也可以手动过滤它,但因为大多数程序员都忘记了字符,所以很难达到这个效果。
复制代码代码如下所示:
一个准备好的语句
如果(美元支撑=美元mysqli ->准备(选择用户名,用户状态=)){
绑定参数
支撑美元-> bind_param(
执行
支撑美元->执行();
结果变量
支撑美元-> bind_result($用户名);
取/ /值
支撑美元->取();
printf(%s为%s
支撑美元->关闭();
}
10。将IP地址存储为无符号整数。
很多程序员没有意识到他们可以存储IP地址在一个整数的形式创建一个VARCHAR(15)时,当你有一个int型,你只占用4字节的空间,这是一个固定大小的区域。
您必须确保所操作的列是一个无符号int类型,因为IP地址将使用32位无符号整数。
r =更新用户设置IP = inet_aton({ } { } _server美元'remote_addr ' '),user_id = $ user_id ;
11。总是为每个表设置一个ID
我们应该建立一个ID为每个数据库中的表的主键,而且最好的是一个int型(推荐使用无符号),并成立了一个auto_increment标志自动添加。
即使你的用户表有一个字段和一个主密钥称为电子邮件,你不让它的主键,VARCHAR类型的使用为主键会降低性能。此外,在你的程序中,你应该使用表的ID来构造你的数据结构。
此外,在MySQL数据引擎下,仍然存在一些需要使用主键的操作。在这种情况下,主键的性能和设置变得非常重要,如集群、分区等。
在这里,只有一个例外,那就是,链接表的外键,也就是说,该表的主键是由单个表的几个主要关键。我们称这个外键。例如,有一个学生的桌子,有学生证,有一个课程表的ID,所以成绩表的相关表,它涉及学生表和课程表,在成绩表、学生证和课程编号叫外键,主键一起构成。
12。而不是使用varchar枚举
枚举类型是非常快速和紧凑的。事实上,它是保存的字段,但其外观显示为一个字符串,它变得相当完美的使用这个字段来做一些选项列表。
如果你有一个领域,如性别、国家、民族、国家或部门,你知道这些字段的值是有限的,固定的,所以你应该使用ENUM而不是VARCHAR。
MySQL也有一个建议(见第十)告诉你如何重新组织你的表结构。当你有一个VARCHAR字段时,这个建议会告诉你把它改变为枚举类型与过程分析()你可以得到一些建议。
13。从过程分析()获得推荐的P程序员站()
过程分析()将让MySQL帮助您分析您的字段及其实际数据,并会给您一些有用的建议。
例如,如果你创建一个int主键字段,但没有太多的数据,然后分析()会建议你改变该字段的类型为MEDIUMINT。或者你使用varchar字段,因为没有太多的数据,你可能会得到一个建议,你可以改变它枚举。这些建议可能是因为数据是不够的,所以决策不够准确。
在后台,你可以通过点击了表结构看表时查看这些建议
请务必注意,这些建议只有在你的表单中有越来越多的数据时才会变得准确。记住,你才是最终做出决定的人。
14。尽可能使用非空PHP程序员站
除非您有一个非常特殊的理由来使用null值,否则您应该始终保持字段不为空,这似乎有点争议。请往下看。
首先,问问自己空与空的区别。(如果它是int,那是0和null),如果你认为它们之间没有区别,你不应该使用null(你知道在Oracle中,空字符串和空字符串是一样的)!
不要认为null不需要空格,它需要额外的空间,当你比较时,你的程序会更复杂。当然,这并不是说你不能使用null,现实是非常复杂的,但在某些情况下,你需要使用null值。
以下是mysql自己的文档:
15。准备好的语句
准备语句非常类似于存储过程。它是在后台运行的SQL语句集合。我们可以通过使用准备好的语句获得很多好处,不管是性能还是安全性。
编写的语句可以检查一些绑定变量,这样可以保护程序不受sql注入攻击的影响,当然,也可以手动检查变量,但是手工检查容易出错,程序员常常忘记,当我们使用某个框架或ORM时,问题会更好。
在性能方面,当相同的查询被多次使用时,它将给您带来相当的性能优势。
虽然MySQL的最新版本在准备语句的传输中使用二进制的情况,这使得网络传输非常高效。
当然,因为它不支持查询缓存的一些情况下,我们需要避免使用准备好的语句。但据说5.1版已支持。在PHP中使用准备好的语句,你可以看看它的使用手册:mysqli扩展或使用数据库抽象层,如PDO。
16。无缓冲的查询
在正常情况下,当您在脚本中执行SQL语句时,程序将停止,直到SQL语句返回,然后程序继续下去。
在这种情况下,有在PHP文件的一个很好的解释:这mysql_unbuffered_query()函数:
上述句子的翻译是mysql_unbuffered_query()发送一个SQL语句MySQL而不是mysql_query()自动fethch和缓存的结果。这将节省相当大的内存,尤其是那些会产生很多结果。你不需要等到所有的结果都回来。您只需要返回第一行数据,您就可以立即开始查询结果。
然而,会有一些限制。因为你读了所有的线,或者你想打电话给mysql_free_result()先下查询()清除的效果。同时,mysql_num_rows mysql_data_seek()或()将不会被使用。所以,如果你使用一个非缓冲的查询,你需要仔细考虑它。
17。将IP地址保存为无符号整数。
很多程序员都会创建一个VARCHAR(15)字段来代替塑料IP字符串形式存储。如果你用塑料来保存它,只需要4个字节,你可以有一个固定长度的字段。此外,这将使你的查询的优势,尤其是当你需要使用这样的一个情况:IP IP1和IP2之间。
我们需要使用无符号int,因为IP地址将使用整个32位无符号的塑料。
为您的查询,您可以使用inet_aton()将一个字符串IP为形式,并使用inet_ntoa()将塑造成一个字符串IP。在PHP,也有这样的功能,ip2long()和long2ip()。
18。定长表会更快。
如果表中的所有字段都是固定长度,整个表格将被视为静态或fixed-length.for例子,没有下面的表中的字段类型:文本,VARCHAR,BLOB。只要你有一个这样的领域,这表不是一个固定长度的静态表,所以MySQL引擎会以另一种方式处理。
固定长度表提高了性能,因为MySQL搜索速度更快,因为这些固定长度很容易计算下一个数据的偏移量,所以自然阅读也会很快发生。如果字段不长,那么,每隔一秒钟查找下一个,你需要程序找到主关键字。
另外,固定长度的表更容易被缓存和重建,但是唯一的副作用是固定长度的字段会浪费一些空间,因为固定长度的字段被分配了很大的空间,不管您是否使用它。
使用垂直分割技术(见下一个),你可以把你的表分成两个,一个是固定的,一个是不长的。
19。垂直分割
垂直分割是一种将数据库中的表转换为列的方法。它可以减少复杂度和字段数,从而达到优化的目的。(在一个银行项目之前,我看到一个有100多个字段的表,非常可怕)。
示例1:用户表中有一个字段,它是家庭地址。此字段为可选字段。当你操作数据库时,除了个人信息外,你不需要阅读或重写这个字段。所以,你为什么不把他放在另一张桌子上,这样你的表就更好了。