当前位置:首页 > 开发教程 > mysql教程 >

Leakon MySQL

时间:2013-04-24 22:46 来源:网络整理 作者:采集侠 收藏

mysql 持久连接 mysql_connect mysql_pconnect 2 years ago by leakon in MySQL 在某些场合,mysql_pconnect( ) 是不适用的。 ——————————————————————————– 状况一: 使用 1 部 web server 与 1 部 MySQL server(两者可能同在一

mysql 持久连接 mysql_connect mysql_pconnect

2 years ago

by leakon in MySQL

在某些场合,mysql_pconnect( ) 是不适用的。

——————————————————————————–

状况一:

使用 1 部 web server 与 1 部 MySQL server(两者可能同在一部主机上),而 web server 固定只对 MySQL server 上的某一个数据库进行存取动作。

因为每次存取数据库时,都是由 web 那边使用同一账号对 MySQL 上的同一数据库作业,若我们将 MySQL 与 web server 的「同时联机数」都调整为 200,就好像 MySQL 这边一直有 200 位「服务生」,随时等着接待来自 web 的 200 位「顾客」似的。而且「顾客」离开之后,「服务生」也不下场休息,时时都站在门口等着接待下一个「顾客」。

在这种情况下,您只要注意将 MySQL 的「同时联机数」调得比 web server 的高或相等,就会发现使用 mysql_pconnect( ) 是个不错的选择。
——————————————————————————–

状况二:

使用 1 部 web server 与 1 部 MySQL server(两者可能同在一部主机上),而 web server 会对 MySQL server 上的两个数据库进行存取动作。

从 web server 那边提出数据存取需求时,有时是针对第 1 个数据库(DB1),有时则是针对第 2 个数据库(DB2)。若我们也将 MySQL 与 web server 的「同时联机数」都调整为 200,这样一来,就好像 MySQL 这边有 200 位「服务生」,但同时经营两个「吧台」(DB1 与 DB2),而「顾客」可能多达 200 位。

一开始,DB1 这个「吧台」比较热门,MySQL 派了 150 位「服务生」上场接待;同样地,当「顾客」离开之后,这 150 位「服务生」仍守着 DB1 而不下场休息。后来,DB2 那边也热闹起来了,「顾客」越来越多,MySQL 得加派「服务生」上场,有几个能派?答案是 50 个!

为什么「服务生」的人力调配会捉襟见肘?那是因为 web 那边使用了 mysql_pconnect( ) 来建立联机。「服务生」一开始被指定到哪个「吧台」工作,就会持续在那边停留,绝不「转台」。
——————————————————————————–

请注意,当使用持续性的联机时,每个已建立的联机只为来自同一部 web server、使用同一组账号,且存取同一数据库的使用者服务。

如此一来,假设每部 web server 的「同时联机数」都是 200,而且同时使用 2 部 web server 会怎么样呢?从 web1 来了 50 个「顾客」,先是到 DB1 走一趟,接着再到 DB2 晃一圈,这样需要多少「服务生」接待他们?100 个(web1->DB1: 50 web1->DB2: 50)!又从 web2 来了 50 个「顾客」,也做了同样的动作(web2->DB1: 50 web2->DB2: 50)。在此之后,还有「服务生」是闲着的吗?后续若从 web1 或 web2 同时涌入多于 50 位「顾客」时,谁来应付他们?

倘若您使用的是像 Apache 这类的 multi-process web server(一个 parent process 协调一组 children processes 运作),某个 children process 建立的「持续联机」,是不能分享给其它 children process 来使用的(「服务生」只对先前接待过的「顾客」服务)。在这样的情况下,将会使得 MySQL 上闲置的 process 越积越多(很多「服务生」站在门口等着「老顾客」上门,而不理会「新顾客」)。
mysql_pconnect( ) 一定是最佳选择吗?我想未必尽然。
——– 两者之间的区别 ————–
mysql_pconnect() 和 mysql_connect() 非常相似,但有两个主要区别。
首先,当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接

标识而不打开新连接。
其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close() 不会关闭由

mysql_pconnect() 建立的连接)。
可选参数 client_flags 自 PHP 4.3.0 版起可用。
此种连接称为”持久的”。
看到这里,写一条代码来测试一下

/*
* pconnect_test.php
*/


;

通过刷新网页的方式执行这条代码,发现每执行一次,mysql的进程数就增加一个。在这里我不禁有了疑问。上面说mysql_pconnect这个函

数的使用的时候,不是说”当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到

,则返回此标识而不打开新连接”么?为什么我每刷新一次页面他就给我打开一个新的连接呢?

考虑到这有可能是PHP的bug,我到PHP的bug列表中找关于和too many connections 有关的条目。
相关的话题主要有三个,分别是

#11966 mysql_pconnect opens new connections with the same parameters
#26117 Persistent connection not reused
#13589 Persistent connections stay open and accumulate

描述比较长,我就不在这里贴,具体的内容你自己去看。重点主要是”当一个进程打开一个mysql的持续连接,只要该进程还存在,这个持续

的连接就不会断开,而且每一个进程会打开一个mysql的持续连接,而不能使用其他进程打开的持续连接”。

MySQL

MySQL IN 条件语句 排序

2 years ago

by leakon in MySQL

有个场景,一个几万条记录的表,主键是 id,我想从表中取 id 为 30,20,80,40 的几条记录。

注意,30,20,80,40,是我预期的顺序,我希望 MySQL 按这样的顺序返回记录。

于是我这样写 SQL:

SELECT * FROM my_table WHERE id IN (30, 20, 80, 40);

结果是,他没有按我给的顺序返回。

怎么办?

查到了 FIELD() 函数。

FIELD(str,str1,str2,str3,…)
Returns the index (position) of str in the str1, str2, str3, … list. Returns 0 if str is not found.

把 SQL 语句改写为:

SELECT * FROM my_table WHERE id IN (30, 20, 80, 40) ORDER BY FIELD(id, 30, 20, 80, 40);

排序过程是:

把选出的记录的 id 在 FIELD 列表中进行查找,并返回位置,以位置作为排序依据。

这样的用法,会导致 Using filesort,是效率很低的排序方式。除非数据变化频率很低,或者有长时间的缓存,否则不建议用这样的方式排序。

把 MySQL 返回的结果,用 PHP 在内存中按 id 顺序重新排列,是个不错的优化方案。

MySQL

MySQL 索引优化

3 years ago

by leakon in MySQL

表中包含 10 万条记录,有一个 datetime 类型的字段。

取数据的语句:

SELECT * FROM my_table WHERE created_at < '2010-01-20';

用 EXPLAIN 检查,发现 type 是 ALL, key 是 NULL,根本没用上索引。

可以确定的是,created_at 字段设定索引了。

什么原因呢?

用 SELECT COUNT(*) 看了一下符合 WHERE 条件的记录总数,居然是 6W 多条!!

难怪不用索引,这时用索引毫无意义,就好像 10 万条记录的用户表,有个性别字段,不是男就是女,在这种字段设置索引是错误的决定。

稍微改造一下上述语句:

SELECT * FROM my_table WHERE created_at BETWEEN '2009-12-06' AND '2010-01-20';

这回问题解决!

符合条件的记录只有几百条,EXPLAIN 的 type 是 range,key 是 created_at,Extra 是 Using where 。

自己总结个准则,索引的目的就是尽量缩小结果集,这样才能做到快速查询。

MySQL

MySQL 多实例运行

3 years ago

by leakon in MySQL

今天要在服务器上运行多个 MySQL,用不同的端口,彼此隔离数据。

我最先想到的办法是下源码,编译多份,编译的时候设置不同的默认路径、端口和 my.cnf 配置文件位置。

被同事劝止……


mysql教程阅读排行

最新文章