Mysql
 sql >> база данни >  >> RDS >> Mysql

Търсите наличност с MySQL (и PHP)?

Ето решение, което изглежда работи:

SELECT t.*, DATEDIFF(t.LatestAvailable, t.EarliestAvailable) AS LengthAvailable
FROM 
   (SELECT u.*,
      COALESCE(b1.End, @StartOfWindow) AS EarliestAvailable,
      COALESCE(b2.Start, @EndOfWindow) AS LatestAvailable
    FROM LettingUnits u
    LEFT OUTER JOIN LettingUnitBookings b1
      ON (u.ID = b1.F_LU_ID AND b1.End BETWEEN @StartOfWindow AND @EndOfWindow)
    LEFT OUTER JOIN LettingUnitBookings b2
      ON (u.ID = b2.F_LU_ID AND b2.Start BETWEEN @StartOfWindow AND @EndOfWindow
          AND b2.Start >= b1.End) -- edit: new term
    ) AS t
LEFT OUTER JOIN LettingUnitBookings x
  ON (t.ID = x.F_LU_ID AND x.Start < t.LatestAvailable AND x.End > t.EarliestAvailable)
WHERE x.ID IS NULL AND DATEDIFF(t.LatestAvailable, t.EarliestAvailable) >= @WindowSize;

Резултатът е:

+-----+-------------+-------------------+-----------------+-----------------+
| ID  | Name        | EarliestAvailable | LatestAvailable | LengthAvailable |
+-----+-------------+-------------------+-----------------+-----------------+
| 123 | Foo Cottage | 2009-01-05        | 2009-01-10      |               5 |
| 123 | Foo Cottage | 2009-01-20        | 2009-01-25      |               5 |
| 456 | Bar Cottage | 2009-01-20        | 2009-01-31      |              11 |
+-----+-------------+-------------------+-----------------+-----------------+

Анализиране на това с EXPLAIN показва, че използва индекси доста добре:

+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref   | rows | Extra                   |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------------------+
|  1 | PRIMARY     | <derived2> | ALL    | NULL          | NULL    | NULL    | NULL  |    9 | Using where             |
|  1 | PRIMARY     | x          | ref    | F_LU_ID       | F_LU_ID | 8       | t.ID  |    2 | Using where; Not exists |
|  2 | DERIVED     | u          | system | NULL          | NULL    | NULL    | NULL  |    1 |                         |
|  2 | DERIVED     | b1         | ref    | F_LU_ID       | F_LU_ID | 8       | const |    0 |                         |
|  2 | DERIVED     | b2         | ref    | F_LU_ID       | F_LU_ID | 8       | const |    0 |                         |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------------------+

Сравнете с EXPLAIN отчет за даденото решение a> от @martin clayton:

+----+--------------+---------------------+--------+---------------+---------+---------+------+------+---------------------------------+
| id | select_type  | table               | type   | possible_keys | key     | key_len | ref  | rows | Extra                           |
+----+--------------+---------------------+--------+---------------+---------+---------+------+------+---------------------------------+
|  1 | PRIMARY      | lu                  | system | PRIMARY,ID    | NULL    | NULL    | NULL |    1 |                                 |
|  1 | PRIMARY      | <derived2>          | ALL    | NULL          | NULL    | NULL    | NULL |    4 | Using where                     |
|  2 | DERIVED      | <derived3>          | ALL    | NULL          | NULL    | NULL    | NULL |    4 | Using temporary; Using filesort |
|  2 | DERIVED      | <derived5>          | ALL    | NULL          | NULL    | NULL    | NULL |    4 | Using where; Using join buffer  |
|  5 | DERIVED      | LettingUnitBookings | ALL    | NULL          | NULL    | NULL    | NULL |    3 |                                 |
|  6 | UNION        | LettingUnitBookings | index  | NULL          | F_LU_ID | 8       | NULL |    3 | Using index                     |
| NULL | UNION RESULT | <union5,6>          | ALL    | NULL          | NULL    | NULL    | NULL | NULL |                                 |
|  3 | DERIVED      | LettingUnitBookings | ALL    | NULL          | NULL    | NULL    | NULL |    3 |                                 |
|  4 | UNION        | LettingUnitBookings | index  | NULL          | F_LU_ID | 8       | NULL |    3 | Using index                     |
| NULL | UNION RESULT | <union3,4>          | ALL    | NULL          | NULL    | NULL    | NULL | NULL |                                 |
+----+--------------+---------------------+--------+---------------+---------+---------+------+------+---------------------------------+

Като цяло искате да избегнете планове за оптимизация, които налагат Using filesort или Using temporary защото това са убийци на представянето. Заявка, използваща GROUP BY почти сигурно ще предизвика този вид оптимизация, поне в MySQL.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Spring Boot + docker-compose + MySQL:Връзката е отказана

  2. Грешка при архивиране с mysqldump в командния ред на mysql

  3. Кога връзките се връщат към пула за връзки с Spring JPA (хибернация) Entity Manager?

  4. Jquery datepicker с Ajax не работи

  5. Управлявайте MySQL с phpMyAdmin на Ubuntu 10.10 (Maverick)