Sql Postgres选择执行顺序不正确
以下查询在Postgres 9.4.5中不起作用Sql Postgres选择执行顺序不正确,sql,postgresql,execution,Sql,Postgresql,Execution,以下查询在Postgres 9.4.5中不起作用 SELECT * FROM ( SELECT M.NAME, M.VALUE AS V FROM METRICS AS M, METRICATTRIBUTES AS A WHERE M.NAME=A.NAME AND A.ISSTRING='FALSE' ) AS S1 WHERE CAST(S1.V AS NUMERIC)<0 继续读下去,看看我为什么把这个问题弄得过于复杂 度量是度量、值对的表。值存储
SELECT * FROM (
SELECT M.NAME, M.VALUE AS V
FROM METRICS AS M, METRICATTRIBUTES AS A
WHERE M.NAME=A.NAME AND A.ISSTRING='FALSE'
) AS S1
WHERE CAST(S1.V AS NUMERIC)<0
继续读下去,看看我为什么把这个问题弄得过于复杂
度量是度量、值对的表。值存储为字符串,值字段的一些值实际上是字符串。METRICATTRIBUTES表标识可能具有字符串值的度量名称。我通过对METRICS表的分析填充了METRICATTRIBUTES表
为了检查,我跑了
SELECT * FROM (
SELECT M.NAME, M.VALUE AS V
FROM METRICS AS M, METRICATTRIBUTES AS A
WHERE M.NAME=A.NAME AND A.ISSTRING='FALSE'
) AS S1
WHERE S1.V LIKE 'a%'
这不会返回任何值(如我所料)。错误似乎在执行计划中。看起来像这样(对不起,我不得不用胖手指)
1->HAS JOIN
2散列条件:((M.NAME::TEXT=(A.NAME)::TEXT))
3序列扫描度量M
4筛选器:((值)::数字哈希
6->在公制属性A上进行顺序扫描
7过滤器:(不是ISSTRING)
我不是这方面的专家(只有一周的Postgres经验),但看起来Postgres正在尝试在应用连接条件(第2行)之前应用强制转换(第4行)。通过这样做,它将尝试对无效字符串值应用强制转换,这正是我试图避免的
使用显式联接编写此语句没有任何区别。将其作为单个select语句编写是我的第一次尝试,从未想到会出现这种类型的问题。这也不起作用
有什么想法吗?从您的计划中可以看到,表
度量值正在被完整扫描(Seq Scan
)并根据您的条件进行过滤:CAST(S1.V为数字)从您的计划中可以看到,表度量值正在被完整扫描(Seq Scan
)并根据您的条件进行过滤:CAST(S1.V为数字)应用条件的顺序不保证,DBMS可以自由地将外部条件推入派生表(有效地完全消除派生表)出于效率考虑。顺便说一句:您应该停止在where
子句中使用那些古老的隐式联接,并使用显式JOIN
运算符。应用条件的顺序没有保证,DBMS可以自由地将外部条件推送到派生表中(有效地完全消除派生表)出于效率考虑。顺便说一句:您应该停止在where
子句中使用那些古老的隐式联接,并使用显式JOIN
运算符。我知道我在度量表中有文本值。但我也知道,对于那些与ISSTRING=FALSE的METRICATTRIBUTES表中的记录匹配的记录,我没有文本值。我犯了错误METRICATTRIBUTES表的唯一目的是从METRICS表中筛选出字符串值。问题是执行顺序挫败了我的计划。@EHorowitz,你可以使用和来控制连接顺序。我知道我在METRICS表中有文本值。但我也知道,我没有这些记录的文本值匹配METRICATTRIBUTES表中ISSTRING=FALSE的记录。我创建METRICATTRIBUTES表的唯一目的是从METRICS表中筛选出字符串值。问题是执行顺序挫败了我的计划。@EHorowitz,您可以使用和来控制连接顺序。
SELECT * FROM (
SELECT M.NAME, M.VALUE AS V
FROM METRICS AS M, METRICATTRIBUTES AS A
WHERE M.NAME=A.NAME AND A.ISSTRING='FALSE'
) AS S1
WHERE S1.V LIKE 'a%'
1 -> HAS JOIN
2 HASH COND: ((M.NAME::TEXT=(A.NAME)::TEXT))
3 SEQ SCAN ON METRICS M
4 FILTER: ((VALUE)::NUMERIC<0::NUMERIC)
5 -> HASH
6 -> Seq Scan on METRICATTRIBUTES A
7 Filter: (NOT ISSTRING)