问题描述
使用 sql Oracle。我创建了一个查询来查找食品订单的总数。
EXPLAIN PLAN FOR
SELECT FOOD.F_NAME,COUNT(ORDERS.O_ORDERID)
FROM ORDERS
INNER JOIN CUSTOMER ON O_CUSTID = C_CUSTID
INNER JOIN FOOD ON C_FOODKEY = F_FOODKEY
GROUP BY FOOD.F_NAME;
SELECT * FROM TABLE(DBMS_XPLAN.disPLAY);
这将返回计划表输出中行 ID 0 处 3250
的成本 (%cpu)。
我了解到非规范化会加快查询速度并降低成本。在这种情况下,我将食物名称从我的表 FOOD
复制到 ORDERS
以避免 INNER JOIN
。我应该获得更好的成本 (%cpu) 使用率。
我接下来使用了这个查询
EXPLAIN PLAN FOR
SELECT ORDERS.F_NAME,COUNT(ORDERS.O_ORDERID)
FROM ORDERS
GROUP BY ORDERS.F_NAME;
SELECT * FROM TABLE(DBMS_XPLAN.disPLAY);
成本 (%cpu) 根本没有变化 - 计划表输出中行 ID 0 处的值为 3120
。
非规范化和去除 INNER JOIN
不是应该改善我的成本吗?在我的情况下,改进是如此微不足道。这里有什么问题?
解决方法
评论太长了。你必须研究执行计划。但是,主键上的连接通常不是特别昂贵。
昂贵的是 GROUP BY
,因为这需要移动数据。您可以尝试在第二个查询中的 F_NAME
上添加索引。
您的数据模型也很不寻常。不清楚为什么名为 FOOD
的列会存储在 CUSTOMER
级别。
C_FOODKEY
应该是最有可能的 O_FOODKEY
有道理
您不需要非规范化。您正在做的是 - 通过连接分解所有行,然后将它们组合在一起。首先不要这样做,而要尝试这样的事情
SELECT FOOD.F_NAME,(SELECT COUNT(*)
FROM ORDERS
WHERE O_FOODKEY = F_FOODKEY) AS fCount
FROM FOOD