While I am doing monitoring with my PostgreSql server, I found out that this query frequently shown up.
select t.oid, t.typname from pg_type t where t.typtype='b'
and because I have a lot of table, that query will take long time to process.
Is it possible for me to custom that query into another query like
select t.oid, t.typname
from pg_type t
left join pg_type base_type on t.typelem=base_type.oid
where t.typtype='b'
and (base_type.oid is null or base_type.typtype='b')
or maybe another suggestion will be good
thank you
Try to find out what issues this query, then you can fix the problem. It may well be some ORM, framework or other tool.
Having extremely many tables, users, schemas or other objects is a bad idea, because the catalogs are not built and indexed for that.
Related
I have very little experience with PostgreSQL and looking for a way using pgadmin to list out the rows across tables with foreign keys so that I can quickly update some records without doing this via a webapp.
All my tables are prefixed with app
I can select * from one table, but don't know what I'm doing beyond that to get the related table data.
SELECT app_choice.choice_text, app_choice.question_id, app_choice_choice_value
FROM app_choice;
INNER JOIN app_projectquestionnairequestion
ON app.questionnaire.id = app_projectquestionnairequestion.id;
Some my choice table is linked to my projectquestionnairequestion table. So basically every question in projectquestionnairequestion has a related choice in the choice table.
But not all questions have a choice available so i need a way to list all the questions to let me add a choice to it?
Sorry for the bad explanation. It's hard to explain when I dont know the terms
Thanks
This is not an answer but a comment that doesn't fit in the comments section. Don't upvote it since I'll remove it.
Your syntax is a bit wrong, but you are not too far from it. Also, you should use "table aliases" as well (c and q below). Your query could look like:
SELECT
c.choice_text, c.question_id, c.choice_value,
q.name -- this would be the "name" column of the second table
FROM app_choice c
INNER JOIN app_projectquestionnairequestion q
ON q.id = c.question_id;
The task at hand is to select musicians (pid) and the amount of instruments each play, including instruments only played at a concert - these instruments might not be in the [plays] table.
I've solved it, but I read that sub queries in a from clause should be avoided if possible. Just out of curiosity, can anyone show me a more effective way? Or is this a good solution? I'm using psql.
select a.pid, sum(a.instr)
from
(
select pid, count(instr) as instr from plays group by pid
union all
select pid, count(instr) as instr from concert group by pid
) as a
group by a.pid;
Such queries are not a issue. The query optimizer of the database will take care of getting the best out of this query. In some cases a INNER JOIN will be converted to exactly the same execution plan as a sub-SELECT.
If you think the query has a problem you can always fire up the EXPLAIN ANALYZE function of psql. This will give you a overview what your query is actually doing. This way you can also compare different ways to write the query.
The example you gave... I do not think you can solve this without sub-queries very easily. I think the way you chose is good. Anything involving some LEFT JOINs will be more difficult to read.
Advantages
Subqueries are advantageous because they structure the query to isolate each part of the statement, perform the same operation that would ordinarily require complex joins and unions and are easier to read.
Disadvantages
When using subqueries the query optimizer may need to perform additional steps so they take longer to execute than a join.
Uncorrelated subqueries are executed one time for each row of the parent query. If this kind of subqueries process a great amount of data, you should expect it to take a very long time to process the data.
Possible solution:
You can create temporary tables for storing the data of subqueries, then use a JOIN for completing the query. Remember that using a JOIN is better than using a subquery. How to Create a Table
Use a with clause. WITH provides a way to write auxiliary statements for use in a larger query. These statements, which are often referred to as Common Table Expressions or CTEs, can be thought of as defining temporary tables that exist just for one query. It allows you to execute a subquery just once instead of executing it for each row. How to Use With Clause
NOTICE: You should avoid using UNION or UNION ALL.
I have seen that PostgreSQL have several statistics depending on every table's OID (like the number of inserts, and so) 1.
What I am looking for is some kind of SELECT query or something that would sum up everything for every table.
It would be something like:
SELECT SUM(pg_stat_get_db_tuples_returned(SELECT oid FROM pg_class));
Or something like that. I would apreciate any help in here.
Do you mean this:
SELECT SUM(pg_stat_get_db_tuples_returned(oid))
from pg_class;
Something like this, with your choice of stats function, aggregates the stats function on all tables except temporary and system catalog tables:
SELECT
sum(pg_stat_get_db_tuples_returned(c.oid))
FROM pg_catalog.pg_class c
INNER JOIN pg_namespace n ON (c.relnamespace = n.oid)
WHERE NOT (n.nspname LIKE ANY(ARRAY['pg_temp%','pg_catalog','information_schema']));
Note that pg_toast schemas are included in this, as I presume you want your stats to include any TOAST side-tables. If you don't, add pg_toast% to the exclusions.
Edit: I was using the construct:
(quote_ident(n.nspname)||'.'||quote_ident(c.relname))::regclass
to get the table oid, but that's just silly when it's right there in pg_class; it's ridiculously roundabout as shown by a_horse_with_no_name.
In PostgreSQL, is there a way to get all of the tables that a view/table depends on based on its use of foreign keys and access to a given table?
Basically, I want to be able to copy the structure of a view/table using a script and want to be able to automatically get the list of tables that I would also need to copy in order for everything to still work right.
This response appears to be headed in the right direction, but doesn't give me the results that I expect/need. Any suggestions?
Using the info from Andy Lester, I was able to come up with the following queries to retrieve the information that I needed.
Get Tables that Foreign Keys refer to:
SELECT cl2.relname AS ref_table
FROM pg_constraint as co
JOIN pg_class AS cl1 ON co.conrelid=cl1.oid
JOIN pg_class AS cl2 ON co.confrelid=cl2.oid
WHERE co.contype='f' AND cl1.relname='TABLENAME'
ORDER BY cl2.relname;
Get Tables that a View or Rules from a Table refer to:
SELECT cl_d.relname AS ref_table
FROM pg_rewrite AS r
JOIN pg_class AS cl_r ON r.ev_class=cl_r.oid
JOIN pg_depend AS d ON r.oid=d.objid
JOIN pg_class AS cl_d ON d.refobjid=cl_d.oid
WHERE cl_d.relkind IN ('r','v') AND cl_r.relname='TABLENAME'
GROUP BY cl_d.relname
ORDER BY cl_d.relname;
Assuming you have your foreign keys set up correctly, use pg_dump to dump the table definitions.
pg_dump -s -t TABLENAME
I think it is a quite bad idea. Just copy the whole database, I think that the application wants to have all data, not only data from one table.
What's more, there are also triggers, that could depend on some tables, but to know that you'd have to make not so easy code analysis.
In psql, adding + to the usual \d gives you a "Referenced by" list along with the table definition.
\d+ tablename
Is there some means of querying the system tables to establish which tables are using what locking schemes? I took a look at the columns in sysobjects but nothing jumped out.
aargh, just being an idiot:
SELECT name, lockscheme(name)
FROM sysobjects
WHERE type="U"
ORDER BY name
take a look at the syslockinfo and syslocks system tables
you can also run the sp_lock proc