2011-09-29 105 views
0

我正在C++中開發一個小應用程序並使用PostgreSQL作爲後端數據庫。與我的數據庫中的其他表一起有一個"projects"表。根據此表的每個主鍵,在我的數據庫中動態添加一個新表。PostgreSQL:如何優化此查詢

例子:

假設項目表包含以下3行:

-------------------------------- 
| Id |Other Columns Goes here | 
-------------------------------- 
| 1 |       | 
-------------------------------- 
| 2 |       | 
-------------------------------- 
| 3 |       | 
-------------------------------- 

因此,在這種情況下,我也有以下三個表 Table1Table2Table3

現在你可能會注意到表名是通過附加項目生成的.Id在固定字符串即結尾「Table」。 對於某些項目也可能沒有生成表格。

例子:

假設項目表包含以下3行:

-------------------------------- 
| Id |Other Columns Goes here | 
-------------------------------- 
| 1 |       | 
-------------------------------- 
| 2 |       | 
-------------------------------- 
| 3 |       | 
-------------------------------- 
在這方面,我可能會發現,只有按照我的數據庫中的兩個表

所以: Table1Table3

現在我只需要獲得所有有效的項目。目前我正在使用以下算法:

//part1 
SELECT * FROM Projects Table 
get the projects info one by one from the results of above query and store them in new instance of my Custom Class Project 
Store the above instance in some contianer e.g Vector say vProjects 
//part 2 
For each Project p in vProject 
if (TableExist(p.Id)) 
Store p in a new container say vValidatedProjects 
Note: The TableExist() method execute the following query: 
SELECT COUNT(*) FROM pg_tables WHERE tablename = 'Table"+ p.Id + "'" 

現在,每件事情都工作正常,但預期!由於上述算法的第二部分,程序執行速度非常慢,如果我們有一千個項目,TableExist()方法也稱爲千次,每次調用這個方法時都會執行一個新的查詢,從而減慢程序的速度:(

在我腦海裏的解決方案是一些這樣的事情

//part1 
SELECT * FROM Projects Table 
WHERE a table exist angainst projets.Id 
get only those projects info for whom a dynamic table exist. From the results of above query and store them in new instance of my Custom Class Project 
Store the above instance in some contianer e.g Vector say vProjects. 

現在這樣只有一個查詢做的工作爲我們而不是N + 1查詢(其中N是沒有行的項目表) 但我不知道如何寫這樣的查詢返回上述結果。請幫助我實現這一點。

+5

「基於此表的新表在我的數據庫動態添加的每個主鍵」。 - 聽起來很糟糕的設計。添加更多數據不需要創建新表格。你能改變設計還是不是一種選擇? –

+0

@MarkByers:我完全同意你的看法,但我沒有別的選擇,因爲我正在做一些其他的設計,我必須忍受它:( – Jame

回答

2

更改設計將是最好的解決方案。

如果這是不是一種選擇,那麼你可以改變第二部分:由

//part 2 
For each Project p in vProject 
if (TableExist(p.Id)) 
Store p in a new container say vValidatedProjects 

Note: The TableExist() method execute the following query: 
SELECT COUNT(*) FROM pg_tables WHERE tablename = 'Table"+ p.Id + "'" 

,首先在projects表中增加一個新的布爾列(讓它projects.TableExists名)

,然後運行您當前的TableExist()功能之一併填充該列。另外,爲項目創建表的代碼,也更新該列和刪除表的代碼也相應地更新列。

然後你的第二個組成部分是:

//part 2 
For each Project p in vProject 
if (p.TableExists) 
Store p in a new container say vValidatedProjects 

Note: The TableExist() method will not be used any more 
1

我寧願在其中有一個project_id的表格,並用where project_id = ...做所有選擇。這將導致更好的表格統計信息,表格優化器將會做得更好。