在foreach中优化sql查询

时间:2017-01-30 11:44:56

标签: mysql foreach query-optimization

我需要帮助优化下面的查询来构建我已经建立的循环日历。

如果用户未能完成日期的所有任务

这是我在forech中使用的查询,它获取当前活动处于活动状态的所有日期。

这是我目前的设置,虽然有效但速度很慢。

其他字符串解释:

$today=date("Y-m-d");
$parts = explode($sepparator, $datespan);
$dayForDate2 = date("l", mktime(0, 0, 0, $parts[1], $parts[2], $parts[0]));
$week2 = strtotime($datespan); 
$week2 = date("W", $week2);
if($week2&1) { $weektype2 = "3"; } # Odd week 1, 3, 5 ... 
else         { $weektype2 = "2"; } # Even week 2, 4, 6 ...

查询1:

$query1 = "SELECT date_from, date_to, bok_id, kommentar
              FROM bokningar
              WHERE bokningar.typ='2'
                and date_from<'".$today."'";

使foreach在当天有一天前进的功能......

function date_range($first, $last, $step = '+1 day', $output_format = 'Y-m-d' )
{

  $dates = array();
  $current = strtotime($first);
  $last = strtotime($last);

  while( $current <= $last ) {

    $dates[] = date($output_format, $current);
    $current = strtotime($step, $current);
  }

  return $dates;
}

的foreach:

foreach (date_range($row['date_from'], $row['date_to'], "+1 day", "Y-m-d")
         as $datespan)
   if ($datespan < $today)

查询2:

$query2 = "
    SELECT bok_id, kommentar
        FROM bokningar b
        WHERE b.typ='2'
          AND b.bok_id='".$row['bok_id']."'
          AND b.weektype = '1'
          AND b.".$dayForDate2." = '1'
          AND NOT EXISTS 
              (SELECT t.tilldelad, t.bok_id
                  FROM tilldelade t
                  WHERE t.tilldelad = '".$datespan."'
                    AND t.bok_id='".$row['bok_id']."')

           OR   b.typ='2'
          AND b.bok_id='".$row['bok_id']."'
          AND b.weektype = '".$weektype2."'
          AND b.".$dayForDate2." = '1'
          AND NOT EXISTS 
                   (SELECT t.tilldelad, t.bok_id
                       FROM tilldelade t
                       WHERE t.tilldelad = '".$datespan."'
                         AND t.bok_id='".$row['bok_id']."')";

b.weektype是1,2或3(每周,每周甚至每周,每个不均匀的一周)

1 个答案:

答案 0 :(得分:1)

INDEX(typ, date_from)需要and date_from < CURDATE()

而不是今天计算$,你可以做

JOIN

您是否为每个日期运行$ query2?这是几天?您可以构建一个日期表,然后bokningar将其设置为SELECTs,以便在一个SELECT中完成所有x AND y OR x AND z

在执行(x AND y) OR (x AND z)时,首先添加括号以清除哪个首先是AND或OR:x AND (y OR z)。然后在布尔算术中使用一个简单的规则将其转换为更有效的表达式:EXISTS(需要parens的地方)。

EXISTS ( SELECT 1 FROM ... )的通常模式是b.weektype;没有必要列出列。

如果我正确阅读,唯一的区别在于测试WHERE。所以WHERE b.weektype IN ('".$weektype2."', '1') AND ... 可以简单地

IN()

不需要OR,因为它实际上在tilldelade

INDEX(tilldelad, bok_id)需要EXISTS(...),无论是哪种顺序。这应该使bokningar运行得更快。

最后,INDEX(typ, bok_id, weektype)按任意顺序需要SHOW CREATE TABLE

这需要改变和测试。看看你是否可以完成这些工作。如果它仍然运行得不够快,请使用新代码启动一个新问题。请为这两个表添加{{1}}。