MySQL 优化Order By Rand()执行效率

lrenwang , 2012/01/15 15:06 , MySQL , 评论(0) , 阅读(25) , Via 本站原创
最近由于需要大概研究了一下MYSQL的随机抽取实现方法。举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。

但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机。

但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上。查看官方手册,也说rand()放在ORDER BY 子句中会被执行多次,自然效率及很低。
You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times.
搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据。
SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id ASC LIMIT 5;
但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。

下面的语句采用的是JOIN,mysql的论坛上有人使用
SELECT *
FROM `table`
WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )
ORDER BY id LIMIT 1;
我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。

于是我把语句改写了一下。
SELECT * FROM `table`
WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)))  
ORDER BY id LIMIT 1;
这下,效率又提高了,查询时间只有0.01秒

最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前 面几行。
完整查询语句是:
SELECT * FROM `table`
WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id) FROM `table`)))  
ORDER BY id LIMIT 1;

SELECT *
FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2
WHERE t1.id >= t2.id
ORDER BY t1.id LIMIT 1;
最后在php中对这两个语句进行分别查询10次,
前者花费时间 0.147433 秒
后者花费时间 0.015130 秒
看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。
IE选项-程序-默认的Web浏览器中去除提示的勾选。 在win7里面这么搞是不好使的 哈哈
另外window7对IE选项-程序 里面所有设置都不好使


经过本人的研究方法如下:
1、开始>>运行>>输入"Regedit"打开注册表;
2、依次定位至"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main";
3、在Main上右键,选择权限;看看组和用户名里面有没有当前用户, 没有就添加上(点添加后,在输入的对象里面填写当前用户, 如果不知道帐号, 我的电脑->控制面板->帐户管理),然后在点击完全控制
4、IE选项-程序-默认的Web浏览器中去除提示的勾选。
成功解决!!


说白了就是当前用户没有操作注册表的权限,自然改不了 ....


关闭ie8设置成默认浏览器的提示也是这么搞

PHP Warning:  PHP Startup: pcinfo: Unable to initialize module
Module compiled with module API=20060613, debug=1, thread-safety=1
PHP    compiled with module API=20060613, debug=0, thread-safety=1
These options need to match

这是说 "Module compiled"  "PHP    compiled" 这两个应该匹配

PHP命名空间规则解析及高级功能

lrenwang , 2012/01/03 23:12 , Php , 评论(0) , 阅读(57) , Via 本站原创
日前发布的PHP 5.3中,最重要的一个新特性就是命名空间的加入。本文介绍了PHP命名空间的一些术语,其解析规则,以及一些高级功能的应用,希望能够帮助读者在项目中真正使用命名空间。

在这里中我们介绍了PHP命名空间的用途和namespace关键字,在这篇文章中我们将介绍一下use命令的使用以及PHP如何解析命名空间的名字的。

为了便于对比,我定义了两个几乎一样的代码块,只有命名空间的名字不同。


< ?php  
// application library 1  
namespace App\Lib1;  
const MYCONST = 'App\Lib1\MYCONST';  
function MyFunction() {  
return __FUNCTION__;  
}  
class MyClass {  
static function WhoAmI() {  
eturn __METHOD__;  
}  
}  
?>

lib2.php

< ?php  
// application library 2  
namespace App\Lib2;  

const MYCONST = 'App\Lib2\MYCONST';  

function MyFunction() {  
return __FUNCTION__;  
}  

class MyClass {  
static function WhoAmI() {  
eturn __METHOD__;  
}  
}  
?>


开始之前先要理解几个PHP命名空间相关术语。

◆完全限定名称(Fully-qualified name)

任何PHP代码都可以引用完全限定名称,它是一个以命名空间反斜线开头的标识符,如\App\Lib1\MYCONST,\App\Lib2\MyFunction( )等。

完全限定名称是没有任何歧义的,开头的反斜线和文件路径的作用有点类似,它表示“根”全局空间,如果我们在全局空间中实现了一个不同的MyFunction( ),可以使用\MyFunction( )从lib1.php或lib2.php调用它。

完全限定名称对一次性函数调用或对象初始化非常有用,但当你产生了大量的调用时它们就没有实用价值了,在下面的讨论中我们将会看到,PHP提供了其它选项以解除我们为命名空间打字的烦恼。

◆限定名称(Qualified name)

至少有一个命名空间分隔符的标识符,如Lib1\MyFunction( )。

◆非限定名称(Unqualified name)

没有命名空间分隔符的标识符,如MyFunction( )。

在相同的命名空间内工作

php 零宽断言

lrenwang , 2012/01/02 20:36 , Php , 评论(0) , 阅读(62) , Via 本站原创
该明白的,你懂的.



<?php
//
$subject = 'abc1';
preg_match_all("/abc(?=\d)/", $subject, $matches);
var_export($matches);echo "\n";
//
$subject = 'abco';
preg_match_all("/abc(?!\d)/", $subject, $matches);
var_export($matches);echo "\n";
//
$subject = '1abc';
preg_match_all("/(?<=\d)abc/", $subject, $matches);
var_export($matches);echo "\n";
//
$subject = '123abc';
//$subject = '000abc';
//$subject = '999abc';
preg_match_all("/(?<=\d{3}(?<!000)(?<!999))abc/", $subject, $matches);
var_export($matches);echo "\n";
?>
分页: 1/35 第一页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]