以下是与您共享的MySQL性能优化的19个要点,并一起学习。

1。优化查询的查询

大多数MySQL服务器打开查询缓存,这是提高性的最有效的方法之一,这是由MySQL数据库引擎处理的。当许多相同的查询多次执行时,这些查询结果将被放入缓存中,以便同一个查询在没有操作表的情况下直接访问缓存结果。

这里的主要问题是程序员很容易忽略。因为我们的一些查询语句,MySQL不使用缓存:


不要打开查询缓存 / / $ R = mysql_query(选择用户名从用户那里signup_date(CURDATE)>); / /查询缓存今天美元=日期(当前);$ R = mysql_query(选择用户名从用户那里signup_date > =美元今天);




以上两个SQL语句之间的区别是CURDATE(),和MySQL的查询缓存不在此工作的功能。所以,SQL函数像现在()和兰德(或)不打开查询缓存,因为这些函数的返回是不确定的,所以你需要使用一个变量取代MySQL的函数,从而开启缓存。

2,解释您的选择查询

使用解释关键字可以让你知道MySQL是如何处理SQL语句的。

有与表相关的查询,如以下:


选择用户名,用户U加入群G的group_name(u.group_id = g.id)


当你发现查询慢,那么指数添加到group_id字段,查询将加速。

三.当使用一行数据时使用限制1

当您查询表一段时间时,您知道将只有一个结果,因为您可能需要转到提取游标,或者您可以检查返回的记录数。

在这种情况下,添加限制1可以提高性能。这样,MySQL数据库引擎将在查找一段数据之后停止搜索,而不是继续查找下一个记录数据。

下面的示例是为了找出是否有一个中国用户,很明显,后面的用户比以前的用户效率更高(注意,第一个是选择*,第二个是select 1)。


没有/效率:r = mysql_query(SELECT * FROM用户所在国=中国);如果(mysql_num_rows(r)> 0){ } / /… / /效率:r = mysql_query(选择1从用户那里country'china极限= 1);如果(mysql_num_rows(r)。0){…


4。索引搜索字段

索引不一定是主键或唯一字段。如果表中有一个字段,您将总是被用来进行搜索。然后,请为它建立索引。

5。在联接表时使用一个相当类型的列并对其进行索引。

如果应用程序有很多连接查询,那么应该确认两个表中的联接字段被索引。

此外,用于联接的字段应该是相同的类型。例如,如果要将十进制字段与int字段连接相结合,MySQL将不能使用它们的索引。

6,千万不要用兰特()命令。

7。避免选择*

数据库中读取的数据越多,查询就越慢。如果数据库服务器和Web服务器是两个独立的服务器,这也会增加网络传输的负载。

所以,你应该养成养成你所需要的好习惯。


/ /不推荐为R = mysql_query(选择*从用户那里user_id = 1);$ a mysql_fetch_assoc(r);echo欢迎{ $ { 'username} }; / / $ R = mysql_query(推荐选择用户名从用户那里user_id = 1)美元mysql_fetch_assoc;a(r);echo欢迎{ $ { 'username} };


8。总是为两个表设置id

我们应该将ID设置为数据库中每个表的主键,最好是int类型(建议无符号),并设置一个自动增长的自动增量标志。

即使你的用户表有一个字段和一个主密钥称为电子邮件,你不让它的主键,VARCHAR类型的使用为主键会降低性能。此外,在你的程序中,你应该使用表的ID来构造你的数据结构。此外,MySQL数据引擎下,还有一些操作需要使用主键。在这种情况下,主键的性能和设置变得非常重要,如集群、分区等。

9。而不是使用varchar枚举

枚举类型是非常快速和紧凑的。事实上,它是保存的字段,但其外观显示为一个字符串,它变得相当完美的使用这个字段来做一些选项列表。

如果你有一个领域,如性别、国家、民族、国家或部门,你知道这些字段的值是有限的,固定的,所以你应该使用ENUM而不是VARCHAR。

10。从过程分析(中)获得建议

过程分析()将让MySQL帮助您分析您的字段及其实际数据,并会给您一些有用的建议。

例如,如果你创建一个int主键字段,但没有太多的数据,然后分析()会建议你改变该字段的类型为MEDIUMINT。或者你使用varchar字段,因为没有太多的数据,你可能会得到一个建议,你可以改变它枚举。这些建议可能是因为数据是不够的,所以决策不够准确。

11。尽可能不要使用null。

除非您有一个非常特殊的理由来使用null值,否则您应该始终保持字段不为空,这似乎有点争议。请往下看。

首先,问一下你的空与空(如果它是int,0和null)有什么区别如果你认为它们之间没有区别,那么你就不用null,你知道吗在Oracle中,空字符串和空字符串是相同的!)

不要认为null不需要空格,它需要额外的空间,当你比较时,你的程序会更复杂。当然,这并不是说你不能使用null,现实是非常复杂的,但在某些情况下,你需要使用null值。

以下是mysql自己的文档

空列需要行中的额外空间来记录是否记录,它也被称为。

12。将IP地址保存为无符号整数。

很多程序员都会创建一个VARCHAR(15)字段来代替塑料IP字符串形式存储。如果你用塑料来保存它,只需要4个字节,你可以有一个固定长度的字段。此外,这将使你的查询的优势,尤其是当你需要使用这样的一个情况:IP IP1和IP2之间。

我们需要使用无符号int,因为IP地址将使用整个32位无符号的塑料。

13。固定长度的表会更快。

如果表中的所有字段都是固定长度,整个表格将被视为静态或fixed-length.for例子,没有下面的表中的字段类型:文本,VARCHAR,BLOB。只要你有一个这样的领域,这表不是一个固定长度的静态表,所以MySQL引擎会以另一种方式处理。

固定长度表提高了性能,因为MySQL搜索速度更快,因为这些固定长度很容易计算下一个数据的偏移量,所以自然阅读也会很快发生。如果字段不长,那么,每隔一秒钟查找下一个,你需要程序找到主关键字。

另外,固定长度的表更容易被缓存和重建,但是唯一的副作用是固定长度的字段会浪费一些空间,因为固定长度的字段是分配了很大的空间,不管您使用与否。

14,垂直分割

垂直分割是一种将数据库中的表转换为列的方法。它可以减少复杂度和字段数,从而达到优化的目的。(在一个银行项目之前,我看到一个有100多个字段的表,非常可怕)。

示例1:用户表中有一个字段,它是家庭地址。此字段为可选字段。当你操作数据库时,除了个人信息外,你不需要阅读或重写这个字段。那么你为什么不把它放在另一个表中呢这会使你的桌子表现更好。如果您考虑一下,在大量的时间内,对于用户表,只会使用用户ID、用户名、密码、用户角色等,较小的表总是有很好的性能。

例二:你有一个名为last_login,将每一次更新用户登录。然而,每一个更新的原因表的查询缓存是空的。所以你可以把这一领域的另一个表中,这样你就不会影响你的用户ID、用户名和用户角色,因为查询缓存可以帮助你提高性能。

此外,您需要注意的是,这些字段形成的表不会定期地连接,否则它们将比未分区的更差。

15,拆分大的删除或插入语句

如果你需要在一个在线网站上执行一个大的删除或插入查询,你必须非常小心避免你的操作和停止你的整个网站。因为这两个操作将锁定表,表被锁定,其他操作不来了。

Apache有很多的子进程或线程,它很有效,我们的服务器不需要太多的子进程,线程和数据库链接。这是服务器资源的一个巨大资源,尤其是内存。

如果你把你的表锁一段时间,比如30秒,那么到一个非常高的流量站点30秒,累积访问过程线程,数据库链接,打开文件的数量,不仅会让你的Web服务崩溃,也会使你的整个服务器立即挂断。

所以,如果你有一个大问题,你要确定它是分裂的,使用极限条件是一个很好的方法:

而(1){ / /每次1000 mysql_query(删除日志log_date '2009-11-01'limit < = 1000);如果(mysql_affected_rows)(= = 0){ / /不可删除,退出!break;} / /每天的休息时间(50000 usleep);}

16,柱子越小,速度越快。

对于大多数数据库引擎来说,硬盘操作可能是最重要的瓶颈,因此,将数据压缩起来是非常有帮助的,因为它减少了对硬盘的访问。

查看MySQL文档存储需求以查看所有数据类型。

如果表中只有几个列(例如,字典表和配置表),那么我们就没有理由使用int来做主键。使用MEDIUMINT,SMALLINT或更小的TINYINT会更经济。如果你不需要记录时间,最好使用datetime日期比。

当然,你还需要留有足够的扩展空间,足够你去做这件事情,你会死的很难看,看到Slashdot的例子(2009年11月06),一个简单的ALTER TABLE语句花了3个多小时,因为有一千六百万个数据。

17。选择正确的存储引擎

有两个MySQL存储引擎MyISAM和InnoDB引擎,各有利弊。前凉壳第MySQL InnoDB和MyISAM:讨论这件事。

MyISAM是适合于一些需要大量查询的应用,但它并不适合大量很好的写操作,即使你只需要一个更新的领域,整个表都会被锁起来,和其他进程,甚至阅读的过程,不能经营到读操作完成。此外,MyISAM是超级快,select count(*)。

InnoDB的趋势将是一个非常复杂的存储引擎,对于一些小的应用会比MyISAM慢。他是支持行锁,所以当写操作是更多,那就更好了。而且他还支持更高级的应用,如业务。

18。小心永久连接

永久链接的目的是为了减少次MySQL链接数是重新创建。当一个链接被创建,它始终处于连接状态,即使数据库操作结束。此外,由于我们的Apache开始重用它的子进程,也就是说,下一个HTTP请求将重用Apache的子进程和重用相同的MySQL链接。

PHP手册:mysql_pconnect()

从理论上讲,这听起来很好,但从个人经验(以及大多数人)来看,这个函数会带来更多麻烦,因为只有有限数量的链接、内存问题、文件句柄数等等。

此外,Apache在一个非常并行的环境中运行,创建了许多进程。这就是为什么这个永久链接的机制不能正常工作的原因。在决定使用一个永久链接之前,您需要考虑整个系统的体系结构。

19。当查询比较慢时,可以使用联接重写查询以进行优化。


MySQL >选择guang_deal_outs哪里deal_id * sql_no_cache(选择ID从guang_deals id是100017151);空白组(18.87秒)MySQL >选择sql_no_cache A. * guang_deal_outs内加入guang_deals B a.deal_id =数据在数据= 100017151;空白组(0.01秒)


原因


MySQL >降序选择guang_deal_outs哪里deal_id * sql_no_cache(选择ID从guang_deals id是100017151);身份证select_type表+ -- + + + + -------------------- ----------------- ------- --------------- + + + + --------- --------- ------- ---------- + ------------- + | | | |型| possible_keys |关键| key_len参考行额外的| | | | + -- + + + + -------------------- ----------------- ------- --------------- + + + + --------- --------- ------- ---------- + ------------- + | 1 |初级| guang_deal_outs所有零| | | |空|空| 18633779 |使用2相关子查询| | | | | guang_deals const初级| | | 4 | const | |使用索引| + -- + + + + -------------------- ----------------- ------- --------------- + --------- + 1 -------- ------- + +—--------- + ------------- + 2行集(0.04秒)可以选择MySQL > sql_no_cache A. * guang_deal_outs内加入guang_deals B a.deal_id =数据在数据= 100017151;+——+ ------------- + ------- + ------- + + + + + ---------------------- --------- ------- ------ + ------------- + | | | select_type进行ID表式possible_keys关键| | | | | key_len参考行额外的| | | + -- + + + + ------------- ------- ------- ---------------------- + + + + ---------------------- --------- ------- ------ + ------------- + | 1 |简单| B | const初级| | | 4 | const | 1 |使用索引1简单的| | | | | REF | idx_guang_dlout_dlid | idx_guang_dlout_dlid | 4 | const | 1 | | + -- + + + + ------------- ------- ------- ---------------------- + ---------------------------- + --- + + + ------- ------ ------------- + 2行集(0.05秒)



事实上,这也是事实guang_deal_outs deal_id.in索引,我想办理查询集


SELECT * FROM guang_deal_outs deal_id在哪里(选择ID从guang_deals id是100017151);


成为继


SELECT * FROM guang_deal_outs deal_id在哪里(100017151);



但不幸的是,实际情况是opposite.mysql试图使它与外部表关联帮助优化查询,认为以下形式的存在更有效


SELECT * FROM guang_deal_outs存在(SELECT * FROM guang_deals id是100017151和ID =);


在子查询的方式是低效的外部数据(如guang_deals以上)是大的,它并不会造成显著影响较小的表。

以上是mysql性能优化的19个关键点分析,希望您能优化mysql的性能帮助。