SQL需要提高运行速度

时间:2017-12-12 15:42:43

标签: php mysql sql query-optimization

我试图通过数据库中的日期字段从mysql中选择数据。 (用户可以输入开始日期和结束日期)

对于用户选择日期之间的每个选定行,我需要从同一个表中选择以产生结果。

示例:

    $query = "SELECT * FROM table WHERE date BETWEEN $begindate AND $enddate"; //Select by date
    $result = mysqli_query($dbc,$query);
    while($row = mysqli_fetch_array($result)){
        vardump($row); //user needs to see all data between date selection
        $query = "SELECT * FROM table WHERE field = $row['field']";
        // and then do calculations with the data
    }

这种运行非常缓慢,我可以理解为什么。如何提高运行速度?

编辑: 最初的目的是在日期之间生成销售报告。现在,用户希望报告生成另一个结果。只能通过搜索同一个表来生成此结果,并且我需要的行不在日期选择范围内。

编辑2: 我确实需要在日期选择之间输出整个表格。每一行都需要找到所有其他行,其中field = field,在日期选择的内部或外部。

编辑3:解决了问题。尽管我认为所选答案与我的问题最相关,但所有答案都有帮助。但是,我相信在使用两个表时使用join是正确的方法。对于我的问题,我实际上只是通过复制表并对重复的表运行我的搜索来解决它。所选答案对我不起作用,因为第二个查询选择不是第一个查询选择的一部分。希望这可以帮助任何人看这篇文章。再次感谢所有的帮助!

3 个答案:

答案 0 :(得分:2)

好吧,如果你真的在同桌中寻找这样的条件,我建议你应该使用IN选择器,如下所示:

$query = "SELECT * FROM table 
           WHERE field IN 
               (SELECT DISTINCT field FROM table 
                WHERE 
                    date BETWEEN $begindate AND $enddate)";

所以最终的代码看起来会像下面这样:

    $query = "SELECT * FROM table 
           WHERE field IN 
               (SELECT DISTINCT field FROM table 
                WHERE 
                    date BETWEEN $begindate AND $enddate)";
    $result = mysqli_query($dbc,$query);
    while($row = mysqli_fetch_array($result)){
        // do calculations with the $row
    }

答案 1 :(得分:1)

我猜你的表名不是TABLE

只是用户inner join

 $query = "SELECT * 
           FROM table1
           JOIN table2 
             ON table1.field = table2.field
           WHERE date BETWEEN $begindate AND $enddate
           ORDER BY table1.field;"

答案 2 :(得分:0)

停止编写伪SQL

SELECT * FROM在技术上是伪SQL(在执行命令之前解释器必须修改的sql命令。最好养成specifying columns in the SELECT statement的习惯。

使用SQL joins

联接是使关系数据库如此有用和强大的原因。学习它们。爱他们。

您的一组SQL查询,合并为一个查询:

SELECT 
    table1.id as Aid, table1.name as Aname, table1.field as Afield,
    table2.id as Bid, table2.name as Bname, table2.field 
FROM table table1
LEFT JOIN table table2 
    ON table1.field = table2.field
WHERE table1.date BETWEEN $begindate AND $enddate
ORDER BY table1.id, table2.id

您生成的数据打印结果应该会导致访问每组数据的内容类似于:

$previous_table1_id = 0;
while($row = mysqli_fetch_array($result)){
    if ($row['Aid'] != $previous_table1_id) {
        echo 'Table1: ' . $row['Aid'] . ' - ' . $row['Aname'] . ' - '. $row['Afield'] . "\n";
        $previous_table1_id = $row['Aid'];
    }

    echo 'Table2: ' . $row['Bid'] . ' - ' . $row['Bname'];
}

处理汇总数据

数据聚合(field上的table1 / table2的多个匹配)是一个复杂的主题,但重要的是要了解。现在,我将告诉你:

以下是汇总数据之一的简化​​示例,以及使用它的无数方法之一。

Contents of Table
id |  name  |  field
--------------------
1  |  foos  |  whoag 
2  |  doh   |  whoag
3  |  rah   |  whoag
4  |  fun   |  wat
5  |  ish   |  wat

Result of query I gave you
Aid | Aname | Afield | Bid | Bname
----------------------------------
1   | foos  | whoag  | 1   | foos
1   | foos  | whoag  | 2   | doh
1   | foos  | whoag  | 3   | rah
2   | doh   | whoag  | 1   | foos
2   | doh   | whoag  | 2   | doh
2   | doh   | whoag  | 3   | rah
3   | rah   | whoag  | 1   | foos
3   | rah   | whoag  | 2   | doh
3   | rah   | whoag  | 3   | rah
4   | fun   | wat    | 4   | fun
4   | fun   | wat    | 5   | ish
5   | ish   | wat    | 4   | fun
5   | ish   | wat    | 5   | ish

GROUP BY缩小结果集

的示例
    SELECT table1.id as Aid, table1.name as Aname
           group_concat(table2.name) as field
    FROM table table1
    LEFT JOIN table table2 
        ON table1.field = table2.field
    WHERE table1.date BETWEEN $begindate AND $enddate
    ORDER BY table1.id, table2.id
    GROUP BY Aid

Aid | Aname | field
----------------------------------
1   | foos  | foos,doh,rah
2   | doh   | foos,doh,rah
3   | rah   | foos,doh,rah
4   | fun   | fun, ish
5   | ish   | fun, ish