PostgreSql Four - Plsql 4 (40 Min)
Temp Table
Type 1
- We are creating a temp table which will be deleted on the commit execution
- It exists only on the current window.
- it does not have physical memory
CREATE TEMP TABLE temp_cities
(
name VARCHAR(80)
)
ON COMMIT DELETE ROWS;
BEGIN TRANSACTION;
INSERT INTO temp_cities VALUES ('Warsaw');
INSERT INTO temp_cities VALUES ('Prague');
INSERT INTO temp_cities VALUES ('Milan');
SELECT COUNT(*) FROM temp_cities;
-- Result: 3
COMMIT;
SELECT COUNT(*) FROM temp_cities;
--------------------------------------------------
Type 2
- It exists only on the current window.
- it does not have physical memory
CREATE TEMP TABLE temps as select * from actor;
select * from temps;
drop table if exists temps
Global Temp Table
What is the difference between clauses 'temp table' vs 'global temporary table' in postgresql?
There is no difference in Postgres. As the documentation explains:
The SQL standard also distinguishes between global and local temporary tables, where a local temporary table has a separate set of contents for each SQL module within each session, though its definition is still shared across sessions. Since PostgreSQL does not support SQL modules, this distinction is not relevant in PostgreSQL.
For compatibility's sake, PostgreSQL will accept the GLOBAL and LOCAL keywords in a temporary table declaration, but they currently have no effect. Use of these keywords is discouraged, since future versions of PostgreSQL might adopt a more standard-compliant interpretation of their meaning.
--------------------------------------------------
Xml usage
xml in function
create temp table t(x xml) on commit drop;
insert into t values('<?xml version="1.0" encoding="UTF-8"?>
<E-Document>
<Document>
<DocumentParties>
<BuyerParty>
<PartyCode>TEST</PartyCode>
<Name>TEST</Name>
</BuyerParty>
</DocumentParties>
<DocumentInfo>
<DocumentNum>123</DocumentNum>
</DocumentInfo>
<DocumentItem>
<ItemEntry>
<SellerItemCode>9999999</SellerItemCode>
<ItemReserve>
<LotNum>(1)</LotNum>
<ItemReserveUnit>
<AmountActual>3.00</AmountActual>
</ItemReserveUnit>
</ItemReserve>
</ItemEntry>
<ItemEntry>
<SellerItemCode>8888888</SellerItemCode>
<ItemReserve>
<LotNum>(2)</LotNum>
<ItemReserveUnit>
<AmountActual>3.00</AmountActual>
</ItemReserveUnit>
</ItemReserve>
</ItemEntry>
</DocumentItem>
</Document>
</E-Document>
'::xml);
SELECT
unnest(xpath('/E-Document/Document/DocumentInfo/DocumentNum/text()',
x))::text AS docnumber,
unnest( xpath(
'/E-Document/Document/DocumentParties/BuyerParty/ContactData/ContactFirstName/text()',
x))::text AS ContactFirstName,
unnest(xpath('/E-Document/Document/DocumentItem/ItemEntry/SellerItemCode/text()',
x))::text AS itemcode
FROM t
---
create table based on xml
create temp table t(x xml) on commit drop;
insert into t values('<?xml version="1.0" encoding="UTF-8"?>
<E-Document>
<Document>
<DocumentParties>
<BuyerParty>
<PartyCode>TEST</PartyCode>
<Name>TEST</Name>
</BuyerParty>
</DocumentParties>
<DocumentInfo>
<DocumentNum>123</DocumentNum>
</DocumentInfo>
<DocumentItem>
<ItemEntry>
<SellerItemCode>9999999</SellerItemCode>
<ItemReserve>
<LotNum>(1)</LotNum>
<ItemReserveUnit>
<AmountActual>3.00</AmountActual>
</ItemReserveUnit>
</ItemReserve>
</ItemEntry>
<ItemEntry>
<SellerItemCode>8888888</SellerItemCode>
<ItemReserve>
<LotNum>(2)</LotNum>
<ItemReserveUnit>
<AmountActual>3.00</AmountActual>
</ItemReserveUnit>
</ItemReserve>
</ItemEntry>
</DocumentItem>
</Document>
</E-Document>
'::xml);
create table xmltest as
SELECT
unnest(xpath('/E-Document/Document/DocumentInfo/DocumentNum/text()',
x))::text AS docnumber,
unnest( xpath(
'/E-Document/Document/DocumentParties/BuyerParty/ContactData/ContactFirstName/text()',
x))::text AS ContactFirstName,
unnest(xpath('/E-Document/Document/DocumentItem/ItemEntry/SellerItemCode/text()',
x))::text AS itemcode
FROM t
--------------------------------------------------
By the same way you can insert and update rows
CREATE or REPLACE FUNCTION
multiple_bin_update(rack_num xml,
bin_num text)
returns
setof refcursor
language
'plpgsql'
AS
$BODY$
DECLARE
msg text := 'No Values';
BEGIN
update
wm_pckinfo
set c_bin=bin_num WHERE c_rackid IN (
SELECT unnest
(xpath('.//RackID/text()', rack_num::xml))::text AS XMLDATA);
msg := 'Updated';
RETURN NEXT msg;
END;
$BODY$;
--------------------------------------------------
Triggers
CREATE TABLE "Employee"
(
"EmployeeId" INT NOT NULL,
"LastName" VARCHAR(20) NOT NULL,
"FirstName" VARCHAR(20) NOT NULL,
"Title" VARCHAR(30),
"ReportsTo" INT,
"BirthDate" TIMESTAMP,
"HireDate" TIMESTAMP,
"Address" VARCHAR(70),
"City" VARCHAR(40),
"State" VARCHAR(40),
"Country" VARCHAR(40),
"PostalCode" VARCHAR(10),
"Phone" VARCHAR(24),
"Fax" VARCHAR(24),
"Email" VARCHAR(60),
CONSTRAINT "PK_Employee" PRIMARY KEY ("EmployeeId")
);
CREATE TABLE "Employee_Audit"
(
"EmployeeId" INT NOT NULL,
"LastName" VARCHAR(20) NOT NULL,
"FirstName" VARCHAR(20) NOT NULL,
"UserName" VARCHAR(20) NOT NULL,
"EmpAdditionTime" VARCHAR(20) NOT NULL
);
CREATE OR REPLACE FUNCTION employee_insert_trigger_fnc()
RETURNS trigger AS
$$
BEGIN
INSERT INTO "Employee_Audit" ( "EmployeeId", "LastName", "FirstName","UserName" ,"EmpAdditionTime")
VALUES(NEW."EmployeeId",NEW."LastName",NEW."FirstName",current_user,current_date);
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
CREATE TRIGGER employee_insert_trigger
AFTER INSERT
ON "Employee"
FOR EACH ROW
EXECUTE PROCEDURE employee_insert_trigger_fnc();
INSERT INTO "Employee" VALUES(10,' Adams','Andrew','Manager',1,'1962-02-18 00:00:00','2010-08-14 00:00:00','11120 Jasper Ave NW','Edmonton','AB','Canada','T5K 2N1','+1 780 428-9482','+1 780 428-3457','abc@gmail.com');
select * from "Employee" where "EmployeeId" =10;
select * from "Employee_Audit" ;
----------------------------
Uses Of Triggers
1. Auditing: You can use triggers to track the table transactions by logging the event details.
2. Forcing Check Constraint: You can create a trigger by which you can check the constraints before applying the transaction to the table.
3. Automatic Population: By using triggers you can also auto populate tables fields by new transactions records manipulation.
Important Points To Remember
1. To create a trigger on a table, the user must have the TRIGGER privilege on the table and EXECUTE privilege on the trigger function.
2. You can check system catalogue “pg_trigger” for the existing trigger information in the database.
3. If you create multiple triggers on the same object for the same event, those triggers will be fired in alphabetical order by name.
----------------------------
Index
The following query finds the address whose phone number is 223664661973:
SELECT * FROM address
WHERE phone = '223664661973';
Code language: JavaScript (javascript)
It is obvious that the database engine had to scan the whole address table to look for the address because there is no index available for the phone column.
To show the query plan, you use the EXPLAIN statement as follows:
EXPLAIN SELECT *
FROM address
WHERE phone = '223664661973';
Code language: JavaScript (javascript)
Here is the output:
PostgreSQL CREATE INDEX - sequential scan example
To create an index for the values in the phone column of the address table, you use the following statement:
CREATE INDEX idx_address_phone
ON address(phone);
Now, if you execute the query again, you will find that the database engine uses the index for lookup:
EXPLAIN SELECT *
FROM address
WHERE phone = '223664661973';
----------------------------
Tuning
- avoid duplicate query
- select 1 instead of select * in if condition
- use index in large table
- use normalization
- use function if necessary
- use cte instead of using same query two times in a window
- avoid temp table as much as possible it's consume more memory
- use Table Partitioning
- explain query (exc plan) helps to tune performance
----------------------------
Explain plan
The EXPLAIN statement returns the execution plan which PostgreSQL planner generates for a given statement.
The EXPLAIN shows how tables involved in a statement will be scanned by index scan or sequential scan, etc., and if multiple tables are used, what kind of join algorithm will be used.
The most important and useful information that the EXPLAIN statement returns are start-cost before the first row can be returned and the total cost to return the complete result set.
CREATE TABLE authors (
id int4 PRIMARY KEY,
name varchar
);
CREATE TABLE books (
id int4 PRIMARY KEY,
author_id int4,
title varchar
);
If we use the query:
EXPLAIN ANALYZE SELECT authors.name, books.title
FROM books, authors
WHERE books.author_id=16 and authors.id = books.author_id
ORDER BY books.title;
--------------------------------------------------
Comments
Post a Comment