mu已经演示了如何使用表达式索引来解决您的问题。
我注意到使用的函数。对于只有两个整数数组来说,它们似乎过于复杂了。也许这只是对实际情况的简化?无论如何,我很感兴趣,并进行了几个变量的测试。
测试设置
临时表格包含10000个随机整数对:
CREATE TEMP TABLE arr (i int[]);
INSERT INTO arr
SELECT ARRAY[(random() * 1000)::int, (random() * 1000)::int]
FROM generate_series(1,10000);
测试候选人,附带简短的注释来解释每一个:
- mu的查询
CREATE OR REPLACE FUNCTION sort_array1(integer[])
RETURNS int[]
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT array_agg(n) FROM (SELECT n FROM unnest($1) AS t(n) ORDER BY n) AS a;
$func$;
- 在聚合函数内部使用
ORDER BY
(pg 9.0+)与之前相同。
CREATE OR REPLACE FUNCTION sort_array2(int[])
RETURNS int[]
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT array_agg(n ORDER BY n) FROM unnest($1) AS t(n);
$func$;
3.
uralbash的查询
CREATE OR REPLACE FUNCTION sort_array3(anyarray)
RETURNS anyarray
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT ARRAY(
SELECT $1[i]
FROM generate_series(array_lower($1,1), array_upper($1,1)) g(i)
ORDER BY 1)
$func$;
- 将参数更改为
int[]
CREATE OR REPLACE FUNCTION sort_array4(int[])
RETURNS int[]
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT ARRAY(
SELECT $1[i]
FROM generate_series(array_lower($1,1), array_upper($1,1)) g(i)
ORDER BY 1)
$func$;
简化
array_lower()
函数 - 它总是返回1。
CREATE OR REPLACE FUNCTION sort_array5(int[])
RETURNS int[]
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT ARRAY(
SELECT $1[i]
FROM generate_series(1, array_upper($1,1)) g(i)
ORDER BY 1)
$func$;
进一步简化为只有2个元素的情况
CREATE OR REPLACE FUNCTION sort_array6(int[])
RETURNS int[]
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT ARRAY(
SELECT i
FROM (VALUES ($1[1]),($1[2])) g(i)
ORDER BY 1)
$func$;
我的简单查询
CREATE OR REPLACE FUNCTION sort_array7(int[])
RETURNS int[]
LANGUAGE sql STRICT IMMUTABLE AS
$func$
SELECT CASE WHEN $1[1] > $1[2] THEN ARRAY[$1[2], $1[1]] ELSE $1 END;
$func$;
没有 STRICT
修饰符!
CREATE OR REPLACE FUNCTION sort_array8(int[])
RETURNS int[]
LANGUAGE sql IMMUTABLE AS
$func$
SELECT CASE WHEN $1[1] > $1[2] THEN ARRAY[$1[2], $1[1]] ELSE $1 END;
$func$;
结果
我执行了每个约20次,并从EXPLAIN ANALYZE
中选择了最佳结果。
SELECT sort_array1(i) FROM arr
SELECT sort_array2(i) FROM arr
SELECT sort_array3(i) FROM arr
SELECT sort_array4(i) FROM arr
SELECT sort_array5(i) FROM arr
SELECT sort_array6(i) FROM arr
SELECT sort_array7(i) FROM arr
SELECT sort_array8(i) FROM arr
这些是在Debian Squeeze上v9.0.5服务器的结果。在v8.4上也有类似的结果。
我还测试了一些PL/pgSQL变体,它们比预期的要慢一些:对于微小操作来说开销太大,没有查询计划可以缓存。
简单函数(第7个)比其他函数快得多。这是预料之中的,其他变体的开销对于微小数组来说太大了。
去掉STRICT
声明会使速度增加一倍以上。我没有预料到这一点,并发布了这篇后续文章以揭示原因: