Mysql 如何更有效地检查值是否出现在不同的表中?

Mysql 如何更有效地检查值是否出现在不同的表中?,mysql,sql,performance,subquery,Mysql,Sql,Performance,Subquery,我可以通过下面写的查询获取必要的结果。不幸的是,这需要我遍历一个巨大的表,其中包含一个子查询,每次执行该查询都要花费10秒以上的时间。有没有更有效的方法 SELECT * FROM CATEGORIES WHERE ID IN (SELECT DISTINCT replace( CATEGORY, '-', '' ) FROM `LISTINGS`) LIMIT 0 , 30 请注意:类别值在表列表中写为“-1-”,其中1是类别ID。您可以首先尝试以下操作: SELECT * FROM CA

我可以通过下面写的查询获取必要的结果。不幸的是,这需要我遍历一个巨大的表,其中包含一个子查询,每次执行该查询都要花费10秒以上的时间。有没有更有效的方法

SELECT * FROM CATEGORIES
WHERE ID IN (SELECT DISTINCT replace( CATEGORY, '-', '' ) 
FROM `LISTINGS`) LIMIT 0 , 30

请注意:类别值在表列表中写为“-1-”,其中1是类别ID。

您可以首先尝试以下操作:

SELECT *
FROM CATEGORIES c
WHERE exists (SELECT 1 
              FROM `LISTINGS` l
              WHERE c.id = replace(l.CATEGORY, '-', '' ) 
             )
LIMIT 0 , 30;
MySQL的某些版本以一种非常低效的方式实现,因此这可能会解决问题

如果没有,请尝试添加索引listingscategory并执行以下操作:

SELECT *
FROM CATEGORIES c
WHERE exists (SELECT 1 
              FROM `LISTINGS` l
              WHERE concat('-', c.id, '-') = l.CATEGORY
             )
LIMIT 0 , 30;

这会颠倒比较结果,但允许MySQL使用索引进行查找。

我假设这个巨大的表是LISTINGS,其中的CATEGORY字段是一个索引

你需要换掉它

DISTINCT REPLACE (index_field,'a','b') // Using index; Using temporary
这将首先替换所有值,然后检查是否存在不同的值。 鉴于field LISTINGS.CATEGORY没有 问题值,如“-1”和“-1-”,可以使用distinct like

DISTINCT index_field // Using index for group-by, faster
从表类别中选择字段,我认为该字段的记录要少得多:

SELECT * FROM CATEGORIES WHERE CONCAT('-',ID,'-') IN 
(SELECT DISTINCT(CATEGORY) FROM `LISTINGS`)

你也可以考虑失去--好。

你可以试着用替换类中的“-+”+ ID+'-来消除替换。我的语法可能错误,您可能需要将ID转换为varchar才能做到这一点。看起来不管发生什么,你都必须扫描该表。类别经常变化吗?如果没有,只需将类别ID保存在memcache中,并使用ID进行查询。甚至可以将整个类别对象保存在memcache中。在典型用法中,当服务于最终用户时,不应该有理由从数据库中获取类别。