-1

我正在尝试为我的网站的高级搜索编写 mysql 查询,该网站是分类网站,我正在尝试过滤广告,我有:

  • t_userads
  • t_useradsvalues

useradsvalues 包含用户选择的 userad 值,useradsvalues 表结构:

  • ID
  • 用户广告ID
  • 字段ID
  • 选项ID

字段和选项已在另一个表中定义。

例如:需要宝马汽车的广告,颜色字段 ID 为 10,绿色选项 ID 为 33,门字段 ID 为 8,四门选项 ID 为 15

现在我试着写

SELECT
  *
FROM `t_userads`
WHERE
  (`categoryID` = 53 OR `categoryID` = 54 OR `categoryID` = 141)
  AND `countryID` = 8
  AND `ad_active` = 1
  AND `id` IN (
    SELECT
      `useradID`
    FROM `t_useradsvals`
    WHERE (`fieldID` = 10 AND `optionID` = 33) AND `useradID` IN (
      SELECT
        `useradID`
      FROM `t_useradsvals`
      WHERE (`fieldID` = 8 AND `optionID` = 15)
    )
  )

我得到了正确的结果,但是执行 mysql 查询大约需要 6 秒(我有 5000 个广告),这是一个问题,因为如果我有 100,000 个广告会怎样?

谢谢你。

4

1 回答 1

1

您的查询特别慢,因为您在 WHERE 子句中使用了嵌套查询,这意味着查询可能会针对每个行评估重新执行。你在级联中做了两次,所以它做了很多很多额外的计算。

您需要使用 MySQL JOIN:http ://dev.mysql.com/doc/refman/5.0/en/join.html

SELECT a.*
FROM t_userads a
  JOIN t_useradsvals v1 ON a.id = v1.useradID
  JOIN t_useradsvals v2 ON v1.useradID = v2.useradID
WHERE a.categoryID IN (53, 54, 141)
  AND a.countryID = 8 
  AND a.ad_active = 1 
  AND v1.`fieldID` = 10
  AND v1.`optionID` = 33
  AND v2.`fieldID` = 8
  AND v2.`optionID` = 15;

并为 (useradID, fieldID, optionID) 定义一个索引。

如果您只想要 1 个或几个广告,可以在查询末尾使用 LIMIT:http: //dev.mysql.com/doc/refman/5.0/en/select.html

另外,不要查询 *:为什么 SELECT * 被认为是有害的?

于 2013-08-25T05:26:14.380 回答