我需要匹配两个不同表中的城市。 在这两者中,我都有邮政编码和名字。 但是例如,我有一个“ BOURGES”和“ 18000”,另一个有“ BOURGES CEDEX”和“ 18006”。
我第一次尝试:
INNER JOIN b_agence ag ON ag.ville = c.li_commune AND ag.code_postal = c.cd_postal
我将其更改为:
INNER JOIN b_agence a ON (trim(c.li_commune) = trim(replace(a.VILLE,'CEDEX','')) AND left(a.CODE_POSTAL,2) = left(c.cd_postal,2) )
它可以工作,但是很遗憾,我的请求花了30秒以上, 如何以最快的方式实现它?
答案 0 :(得分:0)
请使用存在的位置代替加入 从表1 t1中选择* 哪里存在(从第一个条件的表2 t2中选择顶部1 1 并存在(从第二条件的表2 t3中选择顶部1 1)
答案 1 :(得分:0)
问题在于,通过引入TRIM,您将强制SQL引擎在每次执行查询时进行全表扫描(还包括字符串操作)。如果您希望它很快,请创建一个新的字段,例如VILLE_TRIMMED,并用删除了“ CEDEX”的值一次填充该字段(如果要添加或更改值,则可能必须引入一个触发器来使值保持最新状态),对该新的VILLE_TRIMMED字段建立索引(并确保您的源li_commune字段也已建立索引,并且两个表中的邮政编码字段也都建立索引),然后加入该字段。然后,您的查询可以使用索引进行联接,而不是每次都进行全表扫描,因此速度快了几个数量级。
您会注意到,我们在这里引入了一些非规范化。这是一种常见的模式:标准化以保持数据整洁;速度异常化。
如果您的数据库是SQL Server,则可以将VILLE_TRIMMED用作计算列(对末端的“ CEDEX”进行修整),并将其标记为PERSISTED,然后加入该行。节省了触发器等麻烦,可以使列保持最新状态-SQL Server引擎将解决此问题。