2

我有一种情况要在我where的查询子句中使用 if 条件。indexes在 if 中使用的所有字段都有自己的。但是查询进行了全面table扫描。任何人都可以帮助我避免全表扫描吗?

我的查询:

EXPLAIN SELECT COUNT(*) 
FROM BILL_PATIENT_BILL AS fetchInfo 
WHERE IF(fetchInfo.BILL_TYPE='OP' 
AND fetchInfo.BILL_CATEGORY=0,fetchInfo.DUE_AMOUNT != 0,TRUE)
4

1 回答 1

1
EXPLAIN SELECT COUNT(*) 
FROM BILL_PATIENT_BILL AS fetchInfo 
WHERE IF(fetchInfo.BILL_TYPE='OP' 
AND fetchInfo.BILL_CATEGORY=0,fetchInfo.DUE_AMOUNT != 0,TRUE)

你的 IF 没有任何意义。它的作用是:

  • 如果 BILL_TYPE='OP',
  • 和 BILL_CATEGORY=0,
  • 那么当 DUE_AMOUNT != 0 时 where 子句为真
  • 否则 where 子句始终为真。

但无论如何,你不需要它。您可以使用De Morgan像这样重写查询

EXPLAIN SELECT COUNT(*) 
FROM BILL_PATIENT_BILL AS fetchInfo 
WHERE (fetchInfo.BILL_TYPE='OP' 
  AND fetchInfo.BILL_CATEGORY=0 
  AND fetchInfo.DUE_AMOUNT != 0)
  OR fetchInfo.BILL_TYPE<>'OP'
  OR fetchInfo.BILL_CATEGORY=0

您应该在 (BILL_TYPE,BILL_CATEGORY,DUE_AMOUNT) 上有一个索引,但即便如此,使用 OR 子句,它仍可能决定不使用该索引。如果是这种情况,请尝试将其重写为联合:

SELECT COUNT(*) 
    FROM BILL_PATIENT_BILL AS fetchInfo 
    WHERE (fetchInfo.BILL_TYPE='OP' 
      AND fetchInfo.BILL_CATEGORY=0 
      AND fetchInfo.DUE_AMOUNT != 0)
UNION ALL
SELECT COUNT(*)
    FROM BILL_PATIENT_BILL AS fetchInfo 
      WHERE fetchInfo.BILL_TYPE<>'OP'
UNION ALL
SELECT COUNT(*)
    FROM BILL_PATIENT_BILL AS fetchInfo 
      WHERE fetchInfo.BILL_CATEGORY=0

你可以做一个 SUM 来添加这些。

由于您实际上接受了列的所有值,也许您甚至不需要 where 子句...

EXPLAIN SELECT COUNT(
  IF(fetchInfo.BILL_TYPE='OP' 
    AND fetchInfo.BILL_CATEGORY=0 
    AND fetchInfo.DUE_AMOUNT != 0,
  1,
  0)) 
FROM BILL_PATIENT_BILL AS fetchInfo 
于 2012-09-11T09:32:02.993 回答