We often traverse the system tables in the data dictionary to write SHELL scripts or dynamically create data. Here I use PLSQL to demonstrate three methods to traverse a table.
The table structure is as follows,
t_girl=# \d tmp_1; Unlogged table "public.tmp_1" Column | Type | Modifiers----------+-----------------------------+----------- id | integer | log_time | timestamp without time zone |
Here I create a custom type to save my function return values.
create type ytt_record as (id int,log_time timestamp without time zone);
Now let's look at the first function. It is also the most stupid way to traverse.
create or replace function sp_test_record1(IN f_id int) returns setof ytt_record as$ytt$declare i int;declare cnt int;declare o_out ytt_record;begin i := 0; cnt := 0; select count(*) into cnt from tmp_1 where id > f_id; while i < cnt loop select id,log_time into strict o_out from tmp_1 where id > f_id order by log_time desc limit 1 offset i; i := i + 1; return next o_out; end loop;end;$ytt$ language plpgsql;
It takes about 3 milliseconds to execute the result.
t_girl=# select * from sp_test_record1(60); id | log_time ----+---------------------------- 85 | 2014-01-11 17:52:11.696354 73 | 2014-01-09 17:52:11.696354 77 | 2014-01-04 17:52:11.696354 80 | 2014-01-03 17:52:11.696354 76 | 2014-01-02 17:52:11.696354 65 | 2013-12-31 17:52:11.696354 80 | 2013-12-30 17:52:11.098336 85 | 2013-12-27 17:52:11.098336 97 | 2013-12-26 17:52:11.696354 94 | 2013-12-24 17:52:09.321394(10 rows)Time: 3.338 ms
Now let's look at the second function. This is a relatively optimized function. We use the loop traversal structure that comes with the system.
create or replace function sp_test_record2(IN f_id int) returns setof ytt_record as$ytt$declare o_out ytt_record;begin for o_out in select id,log_time from tmp_1 where id > f_id order by log_time desc loop return next o_out; end loop;end;$ytt$ language plpgsql;
The running result shows that the time is less than 1 ms.
t_girl=# select * from sp_test_record2(60); id | log_time ----+---------------------------- 85 | 2014-01-11 17:52:11.696354 73 | 2014-01-09 17:52:11.696354 77 | 2014-01-04 17:52:11.696354 80 | 2014-01-03 17:52:11.696354 76 | 2014-01-02 17:52:11.696354 65 | 2013-12-31 17:52:11.696354 80 | 2013-12-30 17:52:11.098336 85 | 2013-12-27 17:52:11.098336 97 | 2013-12-26 17:52:11.696354 94 | 2013-12-24 17:52:09.321394(10 rows)Time: 0.660 ms
The last function directly returns the result set using return query.
create or replace function sp_test_record3(IN f_id int) returns setof ytt_record as$ytt$begin return query select id,log_time from tmp_1 where id > f_id order by log_time desc ;end;$ytt$ language plpgsql;
This result is equivalent to the SELECT statement directly from the table. The response time is similar to that of the second table.
t_girl=# select sp_test_record3(60); sp_test_record3 ----------------------------------- (85,"2014-01-11 17:52:11.696354") (73,"2014-01-09 17:52:11.696354") (77,"2014-01-04 17:52:11.696354") (80,"2014-01-03 17:52:11.696354") (76,"2014-01-02 17:52:11.696354") (65,"2013-12-31 17:52:11.696354") (80,"2013-12-30 17:52:11.098336") (85,"2013-12-27 17:52:11.098336") (97,"2013-12-26 17:52:11.696354") (94,"2013-12-24 17:52:09.321394")(10 rows)Time: 0.877 mst_girl=#
This article is from "god, let's see it !" Blog, please be sure to keep this source http://yueliangdao0608.blog.51cto.com/397025/1351039