我只是希望有人可以通过多次查询来帮助我加快查询速度。
目标: a single multi query to function as the single queries below.
简单的查询,我正在检查一个表以查看用户是否被禁止,如果没有,我正在获取id的行并将其视图计数更新1.如果用户被禁止,我不希望最后查询完成。
提前感谢您的帮助。
目前的表现大约是 1200ms。(对于facebook graph api查询,平均值为+ 1000ms)。
注意: af_freefeed.pageid& af_ban.pageid都在数据库中编入索引。
ALSO:我一直在研究和引用http://www.php.net/manual/en/mysqli.multi-query.php
我无法看到如何使用if()
$fconn = new mysqli($fdbhost, $fdbuser, $fdbpass, $fdbname) or die ('Error connecting to mysqli');
// 12,000 rows for af_ban - bigint(255) : indexed
$q = sprintf('SELECT COUNT(pageid) AS numrowst FROM af_ban WHERE pageid = %s', $banpage);
$readtop = $fconn->query($q);
$rowtop = $readtop->fetch_assoc();
// 1.17 million rows for af_freefeed - bigint(255) : indexed
if($rowtop[numrowst] == 0){
$q = sprintf('SELECT COUNT(pageid) AS numrowsf FROM af_freefeed WHERE pageid = %s', $banpage);
$readf = $fconn->query($q);
$rowf = $readf->fetch_assoc();
// increment views
$read = $fconn->query("Update af_freefeed SET views = views + 1 WHERE pageid = ".$banpage."");
}
$q=$fconn->query("SELECT pagename,views,pageid FROM af_freefeed ORDER BY views DESC LIMIT 0, 20");
unset($q);
unset($rowf);
unset($rowtop);
mysqli_close($fconn);
实际请求时间。
Multi_query#1 如果禁止用户,如何停止多重查询?
可能的竞争者: 943.8181ms。如果已添加:933.1279ms. if banned
如果禁止退出循环,则为10毫秒差异。这让我相信循环在实际应该执行之前完成所有查询,“next_result”。或者我在如何循环功能方面有错误。
将exit;
替换为$thread_id = $fconn->thread_id; $fconn->kill($thread_id);
如果被禁止953.4719ms。 没有收获。
$banpage='234232874008';
$query = "SELECT pagename,views,pageid FROM af_freefeed ORDER BY views DESC LIMIT 0, 2;";
$query .= "SELECT pageid AS isbanned FROM af_ban WHERE pageid = \"".$banpage."\";";
$query .= "SELECT pageid AS isadded FROM af_freefeed WHERE pageid = \"".$banpage."\";";
$query .= "Update af_freefeed SET views = views + 1 WHERE pageid = \"".$banpage."\"";
/* execute multi query */
if ($fconn->multi_query($query)) {
if ($result = $fconn->store_result()) {
while ($row = $result->fetch_row()) {
print_r($row).'<br />';
}
$result->free();
}
if ($fconn->more_results()) {
while ($fconn->next_result()){
if($thisresult = $fconn->store_result()){
while (is_array($row = $thisresult->fetch_array())) {
if(isset($row['isbanned'])){
if($row['isbanned']===''.$banpage.''){
$thread_id = $fconn->thread_id;
$fconn->kill($thread_id);
// exit;
}
}
}
}
}
}
}
unset($query);
unset($result);
unset($thisresult);
Multi_query#2 “当前用于基准”如何在next_result()之后删除结果集中的重复字段?
2.667ms。 / 1032.2499ms。但是print_r在$ thisresults中显示重复字段?
**Array
(
[0] => 37
[id] => 37
[1] => 159616034235
[pageid] => 159616034235
[2] =>
[userid] =>
[3] => 30343
[views] => 30343
[4] => Walmart
[pagename] => Walmart
)**
$query = "SELECT pageid AS isbanned FROM af_ban WHERE pageid = \"".$banpage."\";";
$query .= "SELECT pageid AS isadded FROM af_freefeed WHERE pageid = \"".$banpage."\";";
$query .= "SELECT * FROM af_freefeed ORDER BY views DESC LIMIT 0, 20";
//$query .= "Update af_freefeed SET views = views + 1 WHERE pageid = \"".$banpage."\"";
/* execute multi query */
echo '<pre>';
$i=0;
if ($fconn->multi_query($query)) {
if ($result = $fconn->store_result()) {
//$row = $result->fetch_assoc();
while ($row = $result->fetch_assoc()) {
print_r($row).'<br />';
}
$result->free();
}
if ($fconn->more_results()) {
while ($fconn->next_result()){
if($thisresult = $fconn->store_result()){
while ($row2 = $thisresult->fetch_array()) {
if(isset($row2['isadded'])){
if($row2['isadded']===''.$banpage.''){
$addone = $fconn->query("Update af_freefeed SET views = views + 1 WHERE pageid = ".$banpage."");
}
}
print_r($row2);
}
}
}
}
}
/* determine our thread id */
$thread_id = $fconn->thread_id;
/* Kill connection */
$fconn->kill($thread_id);
//
echo '</pre><hr/>';
答案 0 :(得分:3)
答案 1 :(得分:3)
编辑:现在,结论:(下面的测试用例)
您无法控制多语句查询的后续语句的执行
因此,您可以不以您希望的方式使用multi_query()
。
全部执行,或者不执行任何操作。
关于
Multi_query#2 “当前基准”如何在next_result()之后删除结果集中的重复字段?
使用fetch_assoc()
或fetch_array(MYSQLI_ASSOC)
(两者几乎相同)代替fetch_array()
。
关于multi_query():
我最近使用MySQL C API开发了一个程序,mysqli也使用了它 About multiple-statement query support the documentation states:
执行多语句字符串可以生成多个结果集或行计数指示符。处理这些结果涉及与单语句情况不同的方法:在处理第一个语句的结果后,有必要检查是否存在更多结果并依次处理它们。为了支持多结果处理,C API包括mysql_more_results()和mysql_next_result()函数。只要有更多结果可用,这些函数就会在循环结束时使用。 无法以这种方式处理结果可能会导致与服务器的连接断开。
(强调补充)
这导致得出结论,中止多语句查询不是预期的功能。
此外,当后续查询实际执行时,我没有找到解释的任何资源。
调用next_result()
并不一定意味着查询尚未执行。
编辑:测试案例
为了证明我之前的假设,我创建了一个测试用例:
<?php
$db = new mysqli('localhost', 'root', '', 'common');
$query = 'SELECT NOW() as time;';
$query .= 'SELECT NOW() as time;';
$query .= 'SELECT NOW() as time;';
$query .= 'SELECT NOW() as time;';
if($db->multi_query($query)) {
// Current time
echo "'multi_query()' executed at:\n\t\t"
.date('Y-m-d H:i:s')."\n";
// First result
if($result = $db->store_result()) {
$i = 1;
$row = $result->fetch_assoc();
echo "'NOW()' of result $i:\n\t\t".$row['time']."\n";
$result->free();
// Wait 5 seconds
sleep(5);
// Subsequent results
while($db->more_results() && $db->next_result()) {
$result = $db->store_result();
$row = $result->fetch_assoc();
$i++;
echo "'NOW()' of result $i:\n\t\t".$row['time']."\n";
// Wait 5 seconds
sleep(5);
$result->free();
}
}
}
$db->close();
?>
这导致:
'multi_query()' executed at:
2013-05-10 10:18:47
'NOW()' of result 1:
2013-05-10 10:18:47
'NOW()' of result 2:
2013-05-10 10:18:47
'NOW()' of result 3:
2013-05-10 10:18:47
'NOW()' of result 4:
2013-05-10 10:18:47
鉴于此,显然查询的所有四个语句都是在调用multi_query()
后直接执行的。
如果它们仅在调用next_result()
后执行,那么在循环迭代之间添加的sleep(5)
调用会导致5秒的延迟。
答案 2 :(得分:1)
请在mysql中运行以下查询并检查查询运行时间:
CREATE INDEX pagidIndex ON af_ban (pageid(11));
CREATE INDEX pagidFeedIndex ON af_freefeed (pageid(11));
CREATE INDEX viewsIndex ON af_freefeed (views(11));
答案 3 :(得分:1)
我正在检查一个表以查看用户是否被禁止,如果没有,我将获取id的行并将其视图计数更新为1.
以下查询可帮助您更新查看次数。我假设您已经知道page_id。
UPDATE af_freefeed SET views = views + 1 WHERE page_id =%s且page_id not in(从af_ban选择page_id WHERE page_id =%s);
答案 4 :(得分:0)
你可以尝试这些方法:
$sql = sprintf("SELECT af_freefeed.pageid FROM af_freefeed left join af_ban ".
"on (af_freefeed.pageid = af_ban.pageid) ".
"where af_freefeed.pageid = %s and ".
"af_ban.pageid is null limit 1", $pageid);
替换前两个查询。
结果中存在记录应指示请求资源的未经审核的用户。然后,您可以更新您的观点。
希望这有帮助。