新手问题 SQL 这么写 join 感觉性能略差啊……

hexawing · 2013年06月20日 · 最后由 wppurking 回复于 2013年06月21日 · 3249 次阅读

customer_units,客户单位 customer_unit_aliases,客户单位别称 一单位对应多别称(本来是没必要有这么个“别称”的,但实在是有的单位有好多种简称,这个就不多说了,结构没法改了)。 现在想查单位表包含 z 或者别称表包含 z 的记录,这么写感觉性能略差啊……

SELECT
*
FROM
    `customer_units`
LEFT OUTER JOIN `customer_unit_aliases` ON `customer_unit_aliases`.`customer_unit_id` = `customer_units`.`id`
WHERE
    (
        customer_units. NAME LIKE '%z%'
        OR customer_unit_aliases.unit_alias LIKE '%z%'
    )

执行下来居然要 3693ms。 应该用INNER JOIN

这个 where 要跑 2k * 2k 遍的样子?

你可以分别找出 LIKE '%z%' 的然后合并结果就好了

#1 楼 @luikore 事实上我是用 activerecord 的where写的,这个怎么合并呢……

性能瓶颈可能不是在 join 上,而有可能是在两次 like 模糊匹配上。 你可以试试将 like 换成 = ,比较一下查询时间。 你可以做个全文索引。

#3 楼 @kungs

SELECT
*
FROM
    `customer_units`
LEFT OUTER JOIN `customer_unit_aliases` ON `customer_unit_aliases`.`customer_unit_id` = `customer_units`.`id`
WHERE
    (
        customer_units. NAME = 'z'
        OR customer_unit_aliases.unit_alias = 'z'
    )

我改=了,耗时 2776ms……还是略慢啊。 按 #1 楼 @kungs 说的办法我分开试过,两个条件分别都不到 1ms,但我怎么能把它们合并起来呢

这样试试整出两坨然后合并?

CustomerUnit.where("customer_units.name like '%z%'")
CustomerUnitAlias.where("unit_alias like '%z%'")

合并不就是数组相加 uniq by id 么...

a1 = CustomerUnit.where("customer_units.name like '%z%'").pluck :id
a2 = CustomerUnitAlias.where("unit_alias like '%z%'").pluck :customer_unit_id
CustomerUnit.where id: (a1 + a2).uniq.sort

#7 楼 @luikore 好的,我试了下,速度还可以,明天再试试。谢谢各位。

肯定是分开查快。一旦在单位表里命中(这个速度很快),根本不用取别名表去查。

#1 楼 @luikore 求教 2k * 2k 的原因,貌似我没用全文索引,很喜欢用类似代码。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号