【发布时间】:2013-08-12 01:09:55
【问题描述】:
SELECT m.title , m.run_time FROM movie m WHERE m.run_time < (SELECT AVG (run_time) FROM movie) *1.1 AND m.run_time > (SELECT AVG (run_time) FROM movie) *0.9;
在 postgresql 中花费 4.6 到 8
基本上,它会选择平均运行时间在 10% 以内的电影的标题和运行时间。电影表是这样的:
CREATE TABLE MOVIE
(
title varchar(40) NOT NULL,
production_year smallint NOT NULL,
country varchar(20) NOT NULL,
run_time smallint NOT NULL,
major_genre varchar(15) ,
CONSTRAINT pk_movie PRIMARY KEY(title,production_year)
);
并且有 101 个条目。
由于“SELECT AVG (run_time) FROM movie”被使用了两次,我想将平均值粘贴到一个变量中,并在第二个查询中引用该变量。 Mysql长这样,运行起来,两个命令的时间总和比上面的参考查询要短。
SET @average = (SELECT AVG (run_time) FROM movie);
SELECT m.title , m.run_time FROM movie m WHERE m.run_time < @average *1.1 AND m.run_time > @average *0.9;
现在,如何在 postgresql 中等效地执行此操作?我在下面列出了我的尝试
当我尝试在 postgresql 中创建变量时,如下所示:
\set average (SELECT AVG (run_time) FROM movie);
这行得通。但下一行:
SELECT m.title , m.run_time FROM movie m WHERE m.run_time < :average *1.1 AND m.run_time > :average *0.9;
ERROR: syntax error at or near "FROMmovie"
LINE 1: ...OM movie m WHERE m.run_time < (SELECTAVG(run_time)FROMmovie)...
发生,我认为是因为 \set 按字面意思放置我的命令,就像一个字符串变量,并且不像 mysql 那样评估它。
所以我尝试做一个临时表
CREATE TEMP TABLE temptable ( theaverage float );
insert into temptable ( SELECT AVG (m.run_time) FROM movie m );
SELECT m.title , m.run_time FROM movie m WHERE m.run_time < (Select * from temptable) *1.1 AND m.run_time > (Select * from temptable) *0.9;
这些工作。但是(测量)性能不太好。
explain analyze CREATE TEMP TABLE temptable ( theaverage float ); //cannot analyze this/does not work/syntax error happens.
ERROR: syntax error at or near "float"
LINE 1: ...in analyze CREATE TEMP TABLE temptable ( theaverage float );
explain insert into temptable ( SELECT AVG (m.run_time) FROM movie m ); //costs 2.3ish
explain SELECT m.title , m.run_time FROM movie m WHERE m.run_time < (Select theaverage from temptable) *1.1 AND m.run_time > (Select theaverage from temptable) *0.9;
//成本 63 到 66,什么?这将使其成本大大高于未优化的查询,即 4.6 到 8。
我也尝试过 SELECT INTO,但我不知道如何正确使用它来达到我的目的。
那么,我再重复一遍这个问题,如何制作一个优化版本的
"SELECT m.title , m.run_time FROM movie m WHERE m.run_time < (SELECT AVG (run_time) FROM movie) *1.1 AND m.run_time > (SELECT AVG (run_time) FROM movie) *0.9;"
也许通过在 postgresql 中使用变量和性能测量?
【问题讨论】:
标签: mysql sql database postgresql optimization