sql >> Database teknologi >  >> RDS >> Mysql

Søger du efter tilgængelighed med MySQL (og PHP)?

Her er en løsning, der ser ud til at virke:

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;
 

Outputtet er:

+-----+-------------+-------------------+-----------------+-----------------+ | 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 | +-----+-------------+-------------------+-----------------+-----------------+

Analyserer dette med EXPLAIN viser, at den anvender indekser ret godt:

+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------------------+ | 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 | | +----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------------------+

Sammenlign med EXPLAIN rapport for løsningen givet af @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 | | +----+--------------+---------------------+--------+---------------+---------+---------+------+------+---------------------------------+

Generelt vil du undgå optimeringsplaner, der tvinger Using filesort eller Using temporary fordi disse er præstationsdræbere. En forespørgsel, der bruger GROUP BY er næsten sikker på at forårsage denne form for optimering, i hvert fald i MySQL.



  1. PHP-kode til indsæt afkrydsningsfeltværdi i specifik kolonne på mysql med vælg formular

  2. Spørgsmål og svar fra vores Parameter Sniffing-webinarserie

  3. Sådan genereres en eksekveringsplan i SQL Server

  4. Løsning af MySQL-fejl Deadlock fundet, når du forsøger at få lås; prøv at genstarte transaktionen