阿里技术学习博客

分享学习经验

IT博客网 联系 聚合 管理
  40 Posts :: 1 Stories :: 18 Comments :: 0 Trackbacks

2008年12月3日 #

 

http://cn.php.net/proc_open的以下这一段就是原来我也在玩的一个想法!很有意思!

启动一堆php子进程,这些子进程全在监听标准输入,主进程有任务时再把数据扔给子进程!这样应该比每次都生成一堆子进程来得节省资源!

 

 

 

jaroslaw at pobox dot sk
28-Mar-2008 06:15

Some functions stops working proc_open() to me.
This i made to work for me to communicate between two php scripts:

<?php
$abs_path
= '/var/www/domain/filename.php';
$spec = array(array("pipe", "r"), array("pipe", "w"), array("pipe", "w"));
$process = proc_open('php '.$abs_path, $spec, $pipes, null, $_ENV);
if (
is_resource($process)) {
   
# wait till something happens on other side
   
sleep(1);
   
# send command
   
fwrite($pipes[0], 'echo $test;');
   
fflush($pipes[0]);
   
# wait till something happens on other side
   
usleep(1000);
   
# read pipe for result
   
echo fread($pipes[1],1024).'<hr>';
   
# close pipes
   
fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);
   
$return_value = proc_close($process);
}
?>

filename.php then contains this:

<?php
$test
= 'test data generated here<br>';
while(
true) {
   
# read incoming command
   
if($fh = fopen('php://stdin','rb')) {
       
$val_in = fread($fh,1024);
       
fclose($fh);
    }
   
# execute incoming command
   
if($val_in)
        eval(
$val_in);
   
usleep(1000);
   
# prevent neverending cycle
   
if($tmp_counter++ > 100)
        break;
}
?>

 

posted @ 2008-12-03 16:22 阿里爸爸 阅读(24) | 评论 (0)编辑 收藏

2008年11月21日 #

记录一下两个php5实现多任务处理的方式:
一、针对proc_open打开管道的方式
<?php

echo "Programstartsat".date('h:i:s').".\n";

$timeout=10;

$streams=array();

$handles=array();

/*Firstlaunchaprogramwithadelayofthreeseconds,then

onewhichreturnsafteronlyonesecond.*/

$delay=30;

for($id=0;$id<=10;$id++){

 $error_log="".$id.".txt";

 $descriptorspec=array(

  0=>array("pipe","r"),

  1=>array("pipe","w"),

  2=>array("file",$error_log,"w")

 );

 $cmd='sleep '.$delay.';echo "Finishedwithdelayof'.$delay.'".';
echo $cmd."--\n";


 

 $handles[$id]=proc_open($cmd,$descriptorspec,$pipes);

 $streams[$id]=$pipes[1];

 $all_pipes[$id]=$pipes;

 $delay-=2;

}

while(count($streams)){

echo "while------\n";
 $read=$streams;

 stream_select($read,$w=null,$e=null,$timeout);

 foreach($read as $r){

  $id=array_search($r,$streams);

  echo stream_get_contents($all_pipes[$id][1]) . "-\n";

  if(feof($r)){

   fclose($all_pipes[$id][0]);

   fclose($all_pipes[$id][1]);

   $return_value=proc_close($handles[$id]);
echo "--".$return_value."\n";

   unset($streams[$id]);

  }

 }

}

?>



二、针对stream_socket_client打开socket的方式

清单1.同时请求多个HTTP页面

<?php

echo"Programstartsat".date(''h:i:s'').".\n";

$timeout=10;

$result=array();

$sockets=array();

$convenient_read_block=8192;

/*Issueallrequestssimultaneously;there''snoblocking.*/

$delay=15;

$id=0;

while($delay>0){

$s=stream_socket_client("phaseit.net:80",$errno,

$errstr,$timeout,

STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);

if($s){

$sockets[$id++]=$s;

$http_message="GET/demonstration/delay?delay=".

$delay."HTTP/1.0\r\nHost:phaseit.net\r\n\r\n";

fwrite($s,$http_message);

}else{

echo"Stream".$id."failedtoopencorrectly.";

}

$delay-=3;

}

while(count($sockets)){

$read=$sockets;

stream_select($read,$w=null,$e=null,$timeout);

if(count($read)){

/*stream_selectgenerallyshuffles$read,soweneedto

computefromwhichsocket(s)we''rereading.*/

foreach($readas$r){

$id=array_search($r,$sockets);

$data=fread($r,$convenient_read_block);

/*Asocketisreadableeitherbecauseithas

datatoread,ORbecauseit''satEOF.*/

if(strlen($data)==0){

echo"Stream".$id."closesat".date(''h:i:s'').".\n";

fclose($r);

unset($sockets[$id]);

}else{

$result[$id].=$data;

}

}

}else{

/*Atime-outmeansthat*all*streamshavefailed

toreceivearesponse.*/

echo"Time-out!\n";

break;

}

}

?>

如果运行此清单,您将看到如下所示的输出。

清单2.从清单1中的程序获得的典型输出

Programstartsat02:38:50.

Stream4closesat02:38:53.

Stream3closesat02:38:56.

Stream2closesat02:38:59.

Stream1closesat02:39:02.

Stream0closesat02:39:05.

posted @ 2008-11-21 12:09 阿里爸爸 阅读(113) | 评论 (0)编辑 收藏

2008年10月14日 #

     摘要: PHP处理对象部分的内核完全重新开发过,提供更多功能的同时也提高了性能。在以前版本的php中,处理对象和处理基本类型(数字,字符串)的方式是一样的。这种方式的缺陷是:当将对象赋值给一个变量时,或者通过参数传递对象时,对象将被完全拷贝一份。在新的版本里,上述操作将传递引用(可以把引用理解成对象的标识符),而非值。

很多PHP程序员可能甚至没有察觉到老的对象处理方式。事实上,大多数的php应用都可以很好地运行。或者仅仅需要很少的改动。

私有和受保护成员
PHP5引入了私有和受保护成员变量的概念。我们可以用它来定义类成员的可见性。
  阅读全文
posted @ 2008-10-14 01:03 阿里爸爸 阅读(83) | 评论 (0)编辑 收藏

2008年9月9日 #

Mysql Explain 详解


一.语法

explain < table_name >

例如: explain select * from t3 where id=3952602;

二.explain输出解释

+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

1.id
  我的理解是SQL执行的顺利的标识,SQL从大到小的执行.

例如:
mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

很显然这条SQL是从里向外的执行,就是从id=3 向上执行.

2. select_type

就是select类型,可以有以下几种

(1) SIMPLE
简单SELECT(不使用UNION或子查询等) 例如:
mysql> explain select * from t3 where id=3952602;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

(2). PRIMARY

我的理解是最外层的select.例如:

mysql> explain select * from (select * from t3 where id=3952602) a ;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

(3).UNION

UNION中的第二个或后面的SELECT语句.例如
mysql> explain select * from t3 where id=3952602 union all select * from t3 ;
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

(4).DEPENDENT UNION

UNION中的第二个或后面的SELECT语句,取决于外面的查询

mysql> explain select * from t3 where id in (select id from t3 where id=3952602 union all select id from t3)  ;
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table      | type   | possible_keys     | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | t3         | ALL    | NULL              | NULL    | NULL    | NULL  | 1000 | Using where              |
|  2 | DEPENDENT SUBQUERY | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
|  3 | DEPENDENT UNION    | t3         | eq_ref | PRIMARY,idx_t3_id | PRIMARY | 4       | func  |    1 | Using where; Using index |
|NULL | UNION RESULT       | <union2,3> | ALL    | NULL              | NULL    | NULL    | NULL  | NULL |                          |
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+

(4).UNION RESULT

UNION的结果。

mysql> explain select * from t3 where id=3952602 union all select * from t3 ;
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

(5).SUBQUERY

子查询中的第一个SELECT.

mysql> explain select * from t3 where id = (select id from t3 where id=3952602 )  ;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
|  1 | PRIMARY     | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |             |
|  2 | SUBQUERY    | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       |       |    1 | Using index |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+

(6).  DEPENDENT SUBQUERY

子查询中的第一个SELECT,取决于外面的查询

mysql> explain select id from t3 where id in (select id from t3 where id=3952602 )  ;
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | t3    | index | NULL              | PRIMARY | 4       | NULL  | 1000 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+


(7).DERIVED

派生表的SELECT(FROM子句的子查询)

mysql> explain select * from (select * from t3 where id=3952602) a ;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+


3.table

显示这一行的数据是关于哪张表的.
有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)

mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

4.type

这列很重要,显示了连接使用了哪种类别,有无使用索引.
从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL

(1).system

这是const联接类型的一个特例。表仅有一行满足条件.如下(t3表上的id是 primary key)

mysql> explain select * from (select * from t3 where id=3952602) a ;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

(2).const

表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!

const用于用常数值比较PRIMARY KEY或UNIQUE索引的所有部分时。在下面的查询中,tbl_name可以用于const表:
SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1和 primary_key_part2=2;

例如:
mysql> explain select * from t3 where id=3952602;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+


(3). eq_ref

对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。

eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。

在下面的例子中,MySQL可以使用eq_ref联接来处理ref_tables:

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

例如
mysql> create unique index  idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type   | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL    | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+

(4).ref

对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。

ref可以用于使用=或<=>操作符的带索引的列。

在下面的例子中,MySQL可以使用ref联接来处理ref_tables:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

例如:

mysql> drop index idx_t3_id on t3;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> create index idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.04 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL  | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | ref  | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
2 rows in set (0.00 sec)

(5).  ref_or_null

该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。

在下面的例子中,MySQL可以使用ref_or_null联接来处理ref_tables:

SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;

(6). index_merge

该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。

例如:
mysql> explain select * from t4 where id=3952602 or accountid=31754306 ;
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| id | select_type | table | type        | possible_keys              | key                        | key_len | ref  | rows | Extra                                                |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
|  1 | SIMPLE      | t4    | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4     | NULL |    2 | Using union(idx_t4_id,idx_t4_accountid); Using where |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
1 row in set (0.00 sec)

(7). unique_subquery

该类型替换了下面形式的IN子查询的ref:

value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

(8).index_subquery

该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

(9).range

只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。

当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range

mysql> explain select * from t3 where id=3952602 or id=3952603 ;
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys     | key       | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | t3    | range | PRIMARY,idx_t3_id | idx_t3_id | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
1 row in set (0.02 sec)

(10).index

该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

当查询只使用作为单索引一部分的列时,MySQL可以使用该联接类型。

(11). ALL

对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。


5.possible_keys

possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

6. key

key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7.key_len

key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
使用的索引的长度。在不损失精确性的情况下,长度越短越好

8. ref

ref列显示使用哪个列或常数与key一起从表中选择行。

9. rows

rows列显示MySQL认为它执行查询时必须检查的行数。

10. Extra

该列包含MySQL解决查询的详细信息,下面详细.

(1).Distinct
一旦MYSQL找到了与行相联合匹配的行,就不再搜索了

(2).Not exists
MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,

就不再搜索了

(3).Range checked for each

Record(index map:#)
没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

(4).Using filesort
看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

(5).Using index
列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

(6).Using temporary
看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上

(7).Using where
使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题
posted @ 2008-09-09 13:15 阿里爸爸 阅读(93) | 评论 (0)编辑 收藏

2008年7月11日 #

校园里槐花香味弥漫,绿树成荫。门口一阵掌声打破了之前的嘈杂,唐骏微笑着从学生堆里挤出来。

他,曾历任微软中国总裁、盛大总裁,以年薪超过1亿元被媒体称为中国的“打工皇帝”。

“快点,不然就没位置了”一个站在厕所门口,不住的回头看报告厅的女生,朝着厕所门大声喊。“我没吃早餐就冲过来了,可是还是没位置。”一个男生愤愤地说。

唐骏走上演讲台,“我跟你们说一下我的个人密史,是我大学时代的初恋故事。”他神秘的说,台下一片掌声。

他这次是受管理学院院长包国宪教授之邀,做客“全球通”兰州大学管理学院学术论坛,讲述他职业规划的经历。

“在大学里,我很平凡、很普通,普通的让我感动,但我是有追求的。”他略带微笑的说。

本来是380多人的报告厅,现在有700多人,一千多双眼睛直射向唐骏。

三个门口人的密度最大,整个会堂呈三面包围状,前面的同学直接盘腿席地而坐。

唐骏1985年—1990年在日本名古屋大学自动化专业攻读硕士学位。“我考北京邮电大学研究生时是第一名,但没有得到出国留学的机会,”他冷静地说,“我就打电话问有没有剩余的名额,正好北京广播电视学院有一个,我就跑到教育司,李司长说:‘同学,你回去吧。’”

“我没有放弃,”他肯定的说。“每天早上7点,我就跑到教育司门口等李司长,一天、两天、三天,在第六天的时候李司长让我进他的办公室,填了一堆空白资料。”

“我还想要在教育司一直呆到毕业为止,”他笑了笑,“我什么也没做,就是执着。”

1994年,唐骏加入微软,微软当时有12000人,而他只是一个处于末尾的普通的软件工程师。

“在这些超人面前等待?放弃?不,我不放弃,不等待。”他决然的说。

现在英语、德语、日语、阿拉伯语等多语言引擎同时上市,再也不用先下载相应语言的Windows才能看网页了,方便了很多人。

“现在的大学生进入企业就开始抱怨,”他说,“我刚来微软的时候也发现微软有很多问题,但是我没有抱怨,而是利用晚上和周末的时间研究,最后才有多语言引擎的出现。”

“我选择了别人没去做的事情。”他总结说, “在职业生涯中,要学会创造机遇,不是等待机遇。”

“在任何时期、阶段,勤奋是可以弥补不足的,”他双手指挥似的说,“在微软没有人可以站出来说比唐骏更勤奋的。”

2004年2月,唐骏由微软公司退休,同时被公司授予“名誉总裁”称号

“简单+勤奋是我的座右铭,简单做人,勤奋做事。”他笑着说,“要先做人,再做事,偶尔做做秀,人生需要像企业一样经营。”

白色条文衬衣,碎花领带,脸瘦的有点尖,明显的白色上眼皮的他在两个小时的演讲中,每隔两分钟就会有一次笑声或掌声,声音渐小后音响发出砰砰声。

posted @ 2008-07-11 17:45 阿里爸爸 阅读(51) | 评论 (0)编辑 收藏

IT招聘专家和工作场所专家总结了技术专业人员应该掌握的一些具体技能。这些技能会帮助IT专业人员避免工作的低谷和得到薪酬上涨的好处。下面就是让IT人员提高薪酬的10种方法。

  1.熟悉SAAS产品

  IT人员配备和随需应变的咨询公司Bluewolf的共同创始人和负责人Michael Kirven说,SAAS(软件服务)知识在用人要求条件中的比例已经从三年前的5%提高到了35%。拥有这方面知识的人可能很快提高自己的薪酬,无论他们是否知道alesforce、Google Apps或者WorkDay。每一个人都需要知道这些产品如何适合当前的IT架构。

  2.获得SAP知识或者经验

  位于费城的人才和外包服务公司Yoh Services复杂战略和营销的副总裁Jim Lanzalotto称,他支持拥有SAP技术的人,因为SAP技术顾问的需求量和现有人员之间的缺口有3至4万。

  3.获得一个行业的垂直的技术专长

  Kirven说,做一个Java程序员或者一个熟练的.Net开发人员就是一件很好的事情。但是,随着系统越来越复杂,企业不仅需要这些人学些这些编程语言,而且还要了解具体的垂直市场知识,如金融、零售或者媒体,并且了解所有这些知识。

  4.获得一个虚拟化项目

  IT job board Dice网站称,它看到招聘列表中对虚拟化知识人才的需求在过去的六个月里提高了40%,特别是需要了解VMware技术的人。

  5.提高你的商务技能

  Lanzalotto认为,商务经验对于提高IT专业人员的薪金水平是非常重要的。他说,最好的首席信息官不仅仅是一个技术人员,而且应该是能够在技术和业务两个方面都能够工作的业务人员。

  6.获得开源软件产品开发经验

  Kirven说,由于时代已经发生了变化,首席信息官采用MySQL和其它开源软件技术不会有失去工作的风险。事实上,业务人员经常会喜欢开源软件,因为它可能为公司省钱。

  7.更近一步了解能够让你的公司赚钱的技术

  在大型银行或者金融机构工作的人都知道你越接近能够让你的公司赚钱的技术,你的工作岗位对于你的公司就越重要。IT人员也是如此。参与让你的公司增加收入或者节省金钱的项目的IT人员很少会被人忽略。

  8.首席信息官需要架构技能

  Kirven称,IT架构是一个极好的职场道路,不仅因为这是一个高级的职位,而且还因为这些职位几乎完全是不会外包出去的。

  9.付费参加项目管理认证学习的人

  许多研究报名,虽然并非所有的证书都比印刷证书的成本值钱,但是,企业继续付出高价的费用聘用拥有关键证书的人才。其中最最主要的两个项目管理证书是PMP(项目管理专业人员)和PMO(项目管理办公室)。

  10.跳槽

  IT专业人员从一个地方搬迁的另一个地方的比例提高了20%。当你在你的技术专长领域寻求进一步发展时,换一个地理环境也许会有帮助。不同地区对于IT专业人员的技术需求是不同的。

posted @ 2008-07-11 17:34 阿里爸爸 阅读(139) | 评论 (0)编辑 收藏

2008年7月3日 #

宝洁旗下Tremor公司称他们用新方旧法调和,再配以大量秘制调料,揭开了口碑营销的秘密。 

  药剂师们从不指望偶然配成长生不死药,化学家们不会空耗时日炼铅成金,美国宇航局的科学家们也不会徒劳地修补时间机器。

  可是,宝洁公司倒是有一帮人耗费四年时光,要锤炼出营销魔法∶自然而然的口碑,也就是大家告诉大家。他们努力的硕果是打造了一支营销劲旅—Tremor公司,该公司声称已经揭开了口碑妙方的秘密。Tremor筛选出25万名青少年志愿者,构成庞大网络,先与同龄人接触最新的产品和理念。不用说,宝洁希望这些志愿者能够和周围的朋友们分享他们的新体验。这一招收效甚大,促使Tremor开始瞄准另一个目标市场—妈妈们—来施展逐渐成长起来的口碑营销。

  从这一举措背后可以窥见Tremor创造者的奇思妙想。想想这个名字就知道了∶颤栗(tremor)可能是一阵难以捉摸的情感或思绪,转瞬即逝。在Tremor网站的主页上,总是跳动着令参与者们激动的承诺。

  尽管这支劲旅采用的手段充满神秘色彩,宝洁仍然把它奉为营销科学∶旧法新用,通过以技术为后盾的研究加上创新方法来打造客户关系。这并不意味着宝洁愿意把魔法秘密公之于众,但是在接受《市场营销官》杂志采访时,Tremor的首席执行官史蒂夫·诺克斯确实道出了宝洁研发及其成果的许多内幕。他还谈到了现在口碑营销上的知识缺口及其未来发展方向。

  “在Tremor成立的头几年,我们全力去了解口碑在市场上如何发挥作用,”诺克斯说。而且工作还不止于此。“口碑营销是一门动态科学而非静态科学。”

  有些持怀疑态度的人说,口碑营销绝不可能是科学,硬把口碑同营销扯上关系太牵强。有些批评者认为,大肆夸大口碑营销的作用,妄想产生消费者自发宣传品牌的效果,只可能让营销人面对更大的挑战,因为公众会变得更多疑、更轻视广告宣传。但是宝洁这家全球最大的广告客户,不仅打造了一个口碑营销项目,而且专门成立了一个公司来推动口碑营销,其声势绝对能够淹没怀疑者们的声音。

  Tremor的客户数量快速增加。从2001年起,Tremor开始为母公司和其他公司的产品打造广告宣传活动。现在,Tremor为包括梦工厂在内的电影制作公司、可口可乐和丰田等品牌公司制作口碑营销计划。诺克斯说公司80%的品牌宣传活动中都是为其他公司制作的,但是他彬彬有礼地拒绝透露(或确认)任何客户的名称。

  除了宝洁以外,还有许多公司也在尝试把口碑营销由理想转变为真正可靠的分销渠道。口碑营销协会于2004年成立,拥有会员150 家。协会于3月份在芝加哥召开了第一次大会。随着Tremor和类似的口碑营销模式不断发展变化,许多大公司都开始密切关注这个新潮流了。

  Sprint通讯公司的消费者电子商务总监大卫·迪克凯说∶“我们没有宝洁走得那么远。我们还不确定口碑营销会朝哪个方向发展。但是我们先要充分了解这个领域,如果它繁荣发展下去,我们就可以随时加以利用。”  

  口碑营销第一步∶联络员

  推动Tremor前进的是25万名青少年,宝洁称他们为“联络员”。据诺克斯说,从宝洁的最初研究中得出的主要启示就是,这些“联络员”自始至终活跃在产品为市场接受的过程中,因而他们有别于享有“潮流创新者”之称的潮流先驱和早期采用者。这些“潮流创新者”很了解消费者的需求。虽然他们能够迅速接受新产品和新理念,但是却不一定能构成口碑营销的通途大道;有些潮流先驱有可能成为口碑传播的死胡同,因为他们会把只有自己知道的秘密囤积起来,秘而不宣。

  而联络员却不同,即使他们是最后知道秘密的人,也会马上广而告之,告诉身边的人去关注某个新产品、一首酷歌、新电视节目或是新电影。诺克斯认为,这些人有着真正广泛深厚的社会关系网络,而且很愿意同他人交流。

  Tremor的广告宣传取得成功,全要靠这些联络员们的动动嘴、动动手指(敲键盘),因此宝洁投入了大量时间、设计了种种方法来识别他们。第一步是把青少年吸引到Tremor网站(Tremor.com)来。申请参加者一旦登陆,就有各种问题要回答(例如,每天你和多少人交谈?买了新产品有什么感想?)。通过这些问题可以发现候选人的八项个性特征。诺克斯告诉我们其中三个最重要的特征∶好奇,善于交际,善于游说。例如,一个典型联络员的密友名单上,一般都会有150~200个一有消息就联系的朋友。

  在筛选阶段,大概会有15%的申请者能够通过,这些人被称为Tremor的新成员。而没入选的也会被礼貌地拒绝∶“谢谢您对Tremor的关注。很抱歉,这次我们的申请人数已满。”入选者接着将进入“新兵训练营基地”接受严格的训练。Tremor运用各种新理念、新机会吸引他们。比如,Tremor曾发出一封电子邮件,邀请入选者为某部电影提供创意,邮件的标题就是“像好莱坞大腕那样思考”。

  其间,宝洁的员工通过网络在幕后监视他们是否行如其言。简言之,看看这些孩子怎么处理得到的第一口独一份的美味。接下来的就是Tremor的秘方调料了。有8~10%的最初申请者会获得联络员的身份(占目标群体的1%)。即使是更深入Tremor之后,这些正式成员仍然会受到秘密评估,而他们自己浑然不觉。诺克斯坦然承认了这一细节,可是却给Tremor自称的透明度罩上了一层阴影—对任何口碑营销来说,透明度可能都是引起人们争议的焦点吧。

  诺克斯深信,这个精英群体极具影响力,他们是营销人忽视的一支劲旅。的确,像交友网站Fraudster这样的品牌公司,还有BuzzMetrics等口碑营销公司正在拼命追踪联络员型消费者,又称市场影响者、传导者或是蜜蜂。但是,其他准备开展口碑营销的营销人担心这些影响者获得的影响力太大。

  这种辩论常常使Tremor和 BzzAgent陷于争斗之中。BzzAgent的客户包括家乐氏(Kellogg), 拉尔夫劳伦(Ralph Lauren)和啤酒商 Anheuser-Busch等。这家公司自己没有健全的筛选志愿者的专利体系,它的做法是有多少人要多少人(到目前为止,它已拥已有8.6万名志愿者)。志愿者们在线申请,在线签约参加试用新产品,与亲朋好友及其他人交流对产品的感想,然后写成日记发送给BzzAgent。

  与Tremor不同,BzzAgent认为任何顾客——无论是家庭主妇还是首席执行官——都有可能和别人聊聊最新市场动向,而且大部分人也很乐于通过不同的人获得信息。BzzAgent的首席执行官大卫·巴尔特说∶“在制造口碑方面,市场影响者并不比一般人做得更好。人人都可以成为我们的宣传员。”

  口碑营销第二步∶有价值

  一谈到影响者的问题,大部分营销人都认为,如果传递信息的人没有诚意,口碑营销就是无效的。对Tremor来说,在精挑细选了联络员之后,只完成了可信的口碑营销的一半。公司还必须设法精心修饰产品,以便达到口碑营销的最佳效果。

  联络员的关系是在线形成的。但大多数情况下,联络员和产品之间的纽带是在线下结成的∶公司通过邮局寄发给他们礼品包,有贴画,DVD或是样品。Tremor和品牌代表们多次召开会议,反复讨论这些礼品包以及整个宣传活动,看看它们是否能体现两个要素∶可倡导与可扩大。

  可倡导和可扩大的模式是在理论、心理学知识、宝洁现有数据和Tremor的专利调研几个方面结合的基础上建立起来的。用Tremor的行话来说,当联络员自然地体验某种产品、喜欢上它并和同伴谈论它时,就是在倡导产品。诺克斯解释道∶“当联络员刚开始接触一个新想法,他首先会问自己∶‘这个想法值得我广而告之吗?’ 有价值才是他们在社会上‘畅通无阻’的通行证,因而他们所宣传的必须是自己相信的东西。”

  Tremor不会草率地下结论说一个联络员是否对某个产品有所反应。诺克斯说∶“我们有办法找到品牌值得倡导的关键要素,以及联络员倡导这个产品的理由。”

  Tremor口碑营销模式中的第二个要素是可扩大,即某个产品信息或使用体验很容易为人所道,产品能自然而然地进入人们闲谈当中。诺克斯说∶“找到同时具备可倡导和可扩大潜力的口碑理念确非易事。”

  因此,Tremor在开展广告活动之前,要先在一组联络员当中进行信息测试,来寻找最有效用的信息。诺克斯解释说∶“这样做,使我们在产品进入市场前就能够告诉客户说∶‘看见这八个想法了吗?联络员不会谈论它们的。但是这个呢?这个才是他们的热门话题。’”

  Tremor的广告要出色,关键取决于广告活动开始前所掌握的数据量。就是说,只有精心培育,才会产生大量有价值的热门话题。相比之下,BzzAgent的特色则是拥有一套流畅的反馈系统。BzzAgent培训大批“沟通开拓者”,要求他们每周仔细审阅4,000~7,000份数量可观的业务报告,并分别对每份报告做出总结。最后,再从中筛选出有用的信息绘制成图表提供给客户。

  撇开新品发布前期的精心筹划不谈,诺克斯强调,送给联络员的礼品包当中并没有指定的宣传语或是谈话要点。也就是说,即便Tremor竭尽所能培养联络员对产品的积极反应,这些青少年的行为仍是自发、真实的。可倡导和可放大性的要旨,就是“一些理由,使孩子们在自然而然的情形下对别人说:‘嗨,我跟你说过某某产品吗?’”

  他挑选的字眼儿“自然而然的情形”,在某些营销人听来,可能和“可扩大”及“联络员”这样的术语并不相称。难道人的情感刺激或体验真的可能如此地“收放自如”,像积木一样,可随意地拆分或组合?还堂而皇之地称之为“自然而然”?

  技术与互联网战略公司EchoDitto首席执行官尼科·梅尔认为,自觉的口头宣传并不是真正的口碑宣传。他的公司创立了在线社区,帮助客户提升知名度,筹措资金。梅尔说∶“最成功的营销是润物细无声式的,不为人察觉。” 霍华德·迪安2004年总统大选的网站智囊们备受赞誉,因为他们成功地运用了网志和其他互联网工具,拉拢了大批平民支持者。

  诺克斯非常清楚,当新鲜感消失,一切变得程式化,这些联络员就会逐渐感到厌倦。他说∶“这个问题让我夜不成眠。我必须和这些联络员保持一种关系,鼓励他们一直参与我们的活动。”为了使这些孩子们乐此不疲,Tremor每年只让联络员参加20次活动。

  Tremor还有其他办法防止联络员产生厌倦情绪。开展“影响力活动”,即在新品上市前邀请联络员出谋划策,还请他们为现有产品提建议。在Tremor网站上,宝洁用青少年们对产品产生的影响来鼓舞他们的士气。例如,一条大字标题这样写道∶“你告诉了佳洁士你需要什么样的产品!”在宣传香草和樱桃味可乐的“派对炫生活” 主题活动中,联络员提交了各种广告口号,网站上就打出这样的标题∶“你帮助可口可乐挑选了一个口号,它被贴在瓶上发送给了近百万人!”

  据诺克斯说,这类广告活动本身可提倡和可扩大的程度很高,因为青少年个人与品牌有了直接联系。“联络员们可以对所有的朋友说∶‘我帮那条广告挑选了音乐。’这自然而然就把这些孩子们的话题引向广告所涉及的产品了。”

  又是那个字眼儿∶自然而然。  

  口碑营销第三步∶看回报

  营销人备受印刷品和电视广告低迷回报率所困,不知如何才能贴近对媒体退避三舍的消费者群体。Tremor和其他的口碑营销公司引起了这些营销人的注意。出版商企鹅集团营销副总裁李克·帕斯克切罗,四年前首次试水,委托BzzAgent运用口碑营销宣传推广一本企鹅小说。帕斯克切罗说,他现在正和BzzAgent合作实施第24个口碑营销计划。

  当营销人纷纷转向这个新媒介的时候,他们却没有必要的好办法来衡量它的回报。例如,Tremor的口碑营销差不多在联络员的宣传停止后就同时结束了。诺克斯承认说∶“我能评估口碑从Tremor到联络员的宣传效果,最多还能评估从联络员到他们最亲密的朋友的宣传效果。在此之后,就一无所知了。”

  其他口碑营销公司寄希望于先进的口碑营销度量系统。Intelliseek等广告公司开发出各种方法,通过筛读1,100万个网志、信息板和其他网上社区,在线追踪某个品牌的口碑。在线社交网Friendster自诩拥有1,600万会员,声称能够通过追踪会员们在线联系的原因和方法来测量第二级、第三级口碑营销的效果。BuzzMetrics则提供一系列口碑调研和规划服务。他们开发了一项综合服务,用户申请该服务后,每季度都会收到有关某行业各个子市场中(如营养行业)可识别的影响者在线活动的报告和简报。

  BuzzMetrics目前向七家最大的食品公司提供该项服务。

  BuzzMetrics总裁和首席执行官乔纳森·卡森说∶“上千万的消费者在庞大数码数据支持的环境里参与口碑营销活动,这为口碑营销的衡量带来了巨大的可能性,也带来了营销人渴求的消费者责任感。”

  诺克斯指出,相对而言,Tremor的绝大多数客户更关注的是在采用了口碑营销的领域中销售状况如何,而并不是自己的品牌在网络世界里有多大的反响。销售曲线不断出现高峰,这才是驱使帕斯克切罗与BzzAgent继续合作的原因。

  他说∶“和BzzAgent的很多客户一样,我也不怎么看公司提供的图表。”帕斯克切罗更感兴趣的不是BzzAgent复杂的反馈过程,而是反馈的结果。举例说明,2001年9月11日企鹅出版集团出版了一本名为《神酷的艺术》(The Art of Shen Ku)的书。帕斯克切罗用尽了印刷品广告等各种促销手段,但是该书出版一年仍是无人问津。于是他决定尝试口碑营销,期望能让这本书“起死回生”。六个月之后,销售额翻番。帕斯克切罗说∶“如果要在印刷品广告和口碑营销之间选择,我会选择后者。”

  这些成功的案例促使口碑营销在一个个新领域里遍地开花。Tremor感到对青少年受众采用的方法效果很好,现在决定向更贴近宝洁产品线的“妈妈”市场进军。诺克斯说,Tremor需要修改一些筛选问题,例如,把妈妈们“即时通讯名单中的好朋友数量”改成“参加的机构数量”,而联络员的基本概念则会保持不变。Tremor还在尝试其他的招募方法,以便能够捕获这个对技术不敏感、也不怎么上网的消费群体。

  Tremor和客户把目光投向了口碑营销的下一个应用领域—客户保留。诺克斯一直主张,用口碑营销打造品牌忠诚度,要用可倡导和可扩大模式做基础。他问道∶“是什么原因促使联络员从现在起四个月、或是九个月、或是一年半以内向别人谈论某个产品呢?”“我们正和几个客户合作,利用口碑营销来打造会持续多年的长期忠诚度计划。”

  他当然不会说出这些客户的名字,但是如果现行模式能透露什么的话,这些客户一定会享受到一项慷慨的服务套餐,包含有Tremor专用词、影响者信条和热议话题预测等口碑营销科学的种种术语。


 

posted @ 2008-07-03 11:03 阿里爸爸 阅读(142) | 评论 (1)编辑 收藏

2008年7月2日 #

全文索引在 MySQL 中是一个 FULLTEXT 类型索引。FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、VARCHAR 或 TEXT 列上创建。对于大的数据库,将数据装载到一个没有 FULLTEXT 索引的表中,然后再使用 ALTER TABLE (或 CREATE INDEX) 创建索引,这将是非常快的。将数据装载到一个已经有 FULLTEXT 索引的表中,将是非常慢的。

全文搜索通过 MATCH() 函数完成。

mysql> CREATE TABLE articles (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
-> );
Query OK,
0 rows affected (0.00 sec)

mysql
> INSERT INTO articles VALUES
-> (NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'),
-> (NULL,'How To Use MySQL Efficiently', 'After you went through a ...'),
-> (NULL,'Optimising MySQL','In this tutorial we will show ...'),
-> (NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
-> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'),
-> (NULL,'MySQL Security', '