2011-06-12 81 views
1

我有代码来生成从DB四轮车与自己的照片:如何加快此查询?

$l=$database->query("SELECT car,brand,exactprice FROM $table ORDER BY rand() LIMIT 4"); 
$buffer=""; 
foreach($l as $l){ 
    $buffer.="<li><h3>{$l['car']}</h3><p>Price {$l['exactprice']}</p>"; 
    $k=$database->query("SELECT logo FROM logo WHERE brand='{$l['brand']}'"); 
    $buffer.="<img src='{$base_addr}/{$k[0]['logo']}'><br>"; 
} 

这是我当前的代码。我可以重写我的MySQL命令,所以我会从logo中获得logo,并获得我的第一个选择吗?

当前加载此页面需要4.32秒。

+5

-1,SQL-注射代码。 http://stackoverflow.com/questions/6207763/mysql-insert-if-this-ip-dont-have-any-records – Johan 2011-06-12 22:06:22

+0

其不注射,$数据库 - :你应该知道关于这个问题,你之前已经告诉>查询不过滤,使安全输入和输出,感谢抬头anywayz – Zalaboza 2011-06-12 22:13:51

+0

没有也只** **的值,而不是表/列/数据库名,看我的答案和细节,它的链接。 – Johan 2011-06-12 22:24:38

回答

5

您没有提供什么$table了,但无论哪种方式,你可以使用的品牌栏目一个JOIN假设这列是合适的外键)。

SELECT $table.car, $table.brand, $table.exactprice, logo.logo 
FROM $table JOIN logo ON $table.brand = logo.brand 
ORDER BY rand() LIMIT 4 

至于性能,你可以看看在上面的查询前添加EXPLAIN创建你经常使用的列和基准指标。

一些参考退房:

+1

关于基准测试的好处;但即使没有具体的数据,我敢说,每行调用'RAND()'都可能是一个重要的CPU。 – Piskvor 2011-06-12 22:15:10

+0

thankx很多,1.4秒减少:) – Zalaboza 2011-06-12 22:20:03

+0

@Piskvor,关于随机生成4行的任何其他想法? – Zalaboza 2011-06-12 22:21:23

1

SELECT car, $table.brand, exactprice, logo FROM $table JOIN logo ON $table.brand=logo.brand ORDER BY rand() LIMIT 4应该这样做,通过加入brand表到查询。

+0

列 '品牌' 中的字段列表含糊不清 – Zalaboza 2011-06-12 22:16:14

+0

您是否错过了字段列表中'brand'之前的'$ table.'部分?如果您不指定表格,这是不明确的,因为两个表格中都出现了“品牌”列。 – 2011-06-12 22:18:52

1

脚本改成这样:

$l=$database->query("SELECT $table.car, logo.logo, $table.exactprice FROM $table join logo on logo.brand= $table.brand ORDER BY rand() LIMIT 4"); 
     $buffer=""; 
     foreach($l as $l){ 
      $buffer.="<li><h3>{$l['car']}</h3><p>Price {$l['exactprice']}</p>"; 
      $buffer.="<img src='{$base_addr}/{$l['logo']}'><br> 
0

SELECT汽车,品牌,exactprice,标志从$表左连接上($ table.brand = logo.brand)ORDER BY标志兰特()LIMIT 4

+0

我得到这个错误:( 列“品牌”字段列表是不明确的 – Zalaboza 2011-06-12 22:16:31

+0

,这意味着它的两个表中,所以您可以指定在选择 – 2011-06-12 22:43:47

1

目前有2个问题。首先,这个查询应该完成using a JOIN。其他答案中已经提供了查询,所以我不会再重复一遍。

此外,如果您想知道为什么它很慢,它也与ORDER BY rand()有关。对于这一点,你可以检查This Stackoverflow question

1

请做修复SQL注入漏洞:

$allowed_tables = array('table1', 'table2'); 
$table = $_POST['table']; //or wherever table come from. 
if (in_array($table, $allowed_tables)) { 
    $query = "SELECT car,brand,exactprice FROM `$table` ORDER BY rand() LIMIT 4"; 
    $l=$database->query($query); 
    ...... 
} 

使用参数或mysql_real_escape_string(),因为你使用动态的表名不会帮你。
也看到这个问题:How to prevent SQL injection with dynamic tablenames?

1

根据您的表的大小,索引和结构,你可能有其他问题(与EXPLAIN SELECT检查),但有在ORDER BY RAND()一个潜在的问题 - 即排序整个表格,要求RAND()为每行,然后抛出大部分,并给你前四行;效率极低。你可以,但是,做一个子查询巧妙的技巧,例如像this one from @Jan Kneschke's article

SELECT name 
    FROM random JOIN 
     (SELECT CEIL(RAND() * 
        (SELECT MAX(id) 
         FROM random)) AS id 
     ) AS r2 
     USING (id); 

注意,这样只会让你随机分布的结果,只要不存在任何删除的行(或它们均匀分散式);这可能会也可能不是问题,具体取决于查询的目的。请参阅文章进行了深入的讨论:http://jan.kneschke.de/projects/mysql/order-by-rand/

+0

充分披露要:未与该网站关联,它只是有一个很好的解释。 – Piskvor 2011-06-12 22:18:14