左外连接长时间执行

时间:2014-05-20 06:16:35

标签: mysql sql

这是我的mysql查询:

SELECT SUBSTR(`GuestDailyRate`, 3, 8) as price, a.duration as nights, SUBSTR(b.DebtorEffect, 3 , 8) as debtor
FROM `ARR_2013` a OUTER LEFT JOIN `CMDextras` b 
ON a.`GuestCode` = b.`GuestCode`
WHERE a.`GuestCode`=b.`GuestCode` AND b.DebtorEffect NOT LIKE '%(%' AND a.`GuestRateCategory` = 'BestAvaila' AND
YEAR(STR_TO_DATE(a.`ArrivalDate`,'%d-%M-%YY'))=2013 

大约需要5分钟才能显示结果

可以帮我解决。

3 个答案:

答案 0 :(得分:0)

缺少架构和数量级的行数,所以我只能提供一些通用提示:

  1. 确保您在ARR_2013.GuestCode和CMDextras.GuestCode上有索引。你不是在使用外键吗?

  2. 您实际上每个月都使用单独的桌子吗?如果你这样做,这个模式就会失控。

  3. WHERE子句(a。GuestCode = b。GuestCode)已过时,它已被JOIN的ON子句所涵盖。

  4. NOT LIKE'%(%':使用LIKE进行字符串扩展,%字符通常不是很快。完全字符串匹配查询比“LIKE”查询快得多.WHERE消除包含'(''的行 - >也许标记那些带有特殊tinyint列的那些,比如你在编写行时分配的has_parentheses?

  5. STR_TO_DATE:为什么不使用datetime列,这是一种二进制格式,可以更快地对过滤器进行过滤。

答案 1 :(得分:0)

您可以尝试以下查询。但请确保应将连接字段编入索引。

SELECT 
SUBSTR(`GuestDailyRate`, 3, 8) as price, 
a.duration as nights, 
SUBSTR(b.DebtorEffect, 3 , 8) as debtor 
FROM `ARR_2013` a 
JOIN `CMDextras` b 
ON a.`GuestCode` = b.`GuestCode`
WHERE a.`GuestRateCategory` = 'BestAvaila' AND 
b.DebtorEffect NOT LIKE '%(%' AND 
YEAR(STR_TO_DATE(a.`ArrivalDate`,'%d-%M-%YY'))='2013';

您可以通过以下几点进一步优化:

  1. ArrivalDate应该是日期时间而不是字符串。

  2. 如果字段GuestRateCategory上的条件过滤了大量数据,那么您可以索引此字段以获得快速结果。

答案 2 :(得分:0)

首先:您的查询不正确。您在外部连接cmdextras记录,但随后删除WHERE子句中的所有外部联接记录。将b.debtoreffect not like '%(%'移到ON子句以避免这种情况。

select 
  substr(guestdailyrate, 3, 8) as price, 
  a.duration as nights, 
  substr(b.debtoreffect, 3 , 8) as debtor
from arr_2013 a 
outer left join cmdextras b on a.guestcode = b.guestcode 
                            and b.debtoreffect not like '%(%' 
where a.guestratecategory = 'bestavaila' 
and right(a.arrivaldate, 2) = '13';

然后:将日期存储为数据库中的字符串总是很可怕。如果它们存储为日期,您可以使用BETWEEN条款可能更快,只要在到达时有一个索引并且只有一小部分记录在2013年。(看到价格和其他价格也很可怕数据存储为子字符串。我建议更改整个数据库设计。)

唯一的平等标准是guestratecategory。如果只有一小部分行具有值'bestavaila',则需要索引才能使用快速索引查找而不是全表扫描。 (顺便说一下:我会推荐一个类别表而不是存储字符串,而是在这里使用它的id。)

您通过访客代码加入。要使此连接快速执行,请至少在表cmdextras中对guestcode应该有一个索引。

编辑:还有一个想法:您的桌子名为ARR_ 2013 ,您是否正在检查其记录的到达日期 2013 ?到底是什么?