Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Postgres选择执行顺序不正确_Sql_Postgresql_Execution - Fatal编程技术网

Sql Postgres选择执行顺序不正确

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 继续读下去,看看我为什么把这个问题弄得过于复杂 度量是度量、值对的表。值存储

以下查询在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
继续读下去,看看我为什么把这个问题弄得过于复杂

度量是度量、值对的表。值存储为字符串,值字段的一些值实际上是字符串。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)