Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 40

0
votes
answers
32 views
+10

插入表格其中

-1

我正在使用Postgres和Python(psycopg2)。插入表格其中

我正在尋找一種將數據插入到表中的方法。

假設一個有10行的表。 id從1到10.在WHERE條件下取一行(即id = 3),除了2列(col3和col4)外,我的所有列都填充了一些值。含義col1,col2和col5中有值。 col3和col4具有NULL條件,解釋了爲什麼它們首先是空的。

我想用這些數據填充這兩列。

我要尋找類似:

INSERT INTO table_a (col3,col4) WHERE id = 3 VALUES ... 

底線,我想找到的行我應該填寫我的兩個空列與數據,我想。

+1

查看UPDATE SET = WHERE id = xyz'語法 –

+1

INSERT與WHERE組合使用沒有任何意義 - INSERT創建_new_記錄。您想要_UPDATE_現有記錄。 – CBroe

沙发
0
0

我想你想UPDATE,不INSERT

UPDATE table_a 
    SET col3 = ?, 
     col4 = ? 
    WHERE id = 3; 

INSERT插入新行插入表中。 UPDATE更新現有的行。

板凳
0
1

聽起來你正在尋找一個update聲明,而不是insert聲明:

UPDATE table_a 
SET col3 = 'some_value', col4 = 'some_other_value 
WHERE id = 3 
地板
0
0

如果該行已經存在,你正在尋找一個更新,而不是插入。

UPDATE table 
    SET col3 = valueY, 
     col4 = valueX 
WHERE id = 3 

這對你有意義嗎?

97
votes
answers
16 views
+10

Django: permission denied when trying to access database after restore (migration)

I have a django 1.4 app with a populated postgres 9.1 database in development server locally. After successful deployment, I wanted to move the data from local to online database, so I used:

pg_dump -f dump.sql -Ox database

and then restored on the server with:

psql -1 -f dump.sql database

Now trying to login online to the website admin throws a "permission denied for relation django_session" exception. I've tried to dump the data with/without -Ox switch and all its combinations but without success. I am also dropping the database and recreating it from scratch on the server with the correct owner as set in settings.py.

If I run a normal syndb without a restore then everything works well.

Am I missing something here?

up vote 95 down vote accepted favorite
沙发
+950
+50

事實證明,您應該在還原後將數據庫中所有對象的顯式所有權授予所有者。所有者不是超級用戶。僅在數據庫創建時設置所有者是不夠的。遷移的最終解決方案如下:

在客戶端上:

  pg_dump -f dump.sql -Ox database   

在服務器上:

  su postgres dropdb database createdb database -O user psql database -f dump.sql   

然後設置權限:

  psql database -c“在SCHEMA公共用戶的所有表格中全部授予;” psql數據庫-c“在SCHEMA公開給用戶的所有序列中全部授予;” psql數據庫-c“
     
			
        
+20

嘗試從 postgres 用戶執行此操作:

  sudo su  -  postgres pg_dump -f dump.sql -Ox database   < p>或者只是傳遞 -U 標誌: 
  pg_dump -f dump.sql -Ox database -U postgres  
     
			
        

我忘了提,我的客戶端操作系統是Windows 7,沒有postgres su。我只是打開一個DOS提示符並轉儲。 - Rabih Kodeih 12年2月2日2:52

看看更新的答案。使用-U標誌 - Daniil Ryzhkov 12年12月2日在2:54

什麼都沒有改變,仍然有同樣的問題。FWIW,我在服務器上使用一個特殊用戶(客戶端上不存在),這反映在setting.py中,當我在服務器上重新創建數據庫時(恢復之前),我使用類似:createdb的東西數據庫-O special_user然後我恢復。 - Rabih Kodeih 12年2月2日凌晨3點

0

這是我如何修理我的。通過簡單地更改用戶以匹配導入將發生的目標服務器的當前登錄用戶,我為自己省去了大量的麻煩。

在我的例子中,導入的db的用戶為x(x也是運行它的機器的用戶名),目標機器的用戶名為y,postgres用戶為y

因此,我只是在Django設置中更改了數據庫用戶和密碼,以匹配目標機器的y用戶詳細信息。

然後執行了此操作:

$ sudo -u postgres psql psql&gt; 授予所有特權數據庫mydb to y;

現在喝一些kool-aid!

75
votes
answers
21 views
+10

Steps to Troubleshoot “django.db.utils.ProgrammingError: permission denied for relation django_migrations”

What are some basic steps for troubleshooting and narrowing down the cause for the "django.db.utils.ProgrammingError: permission denied for relation django_migrations" error from Django?

I'm getting this message after what was initially a stable production server but has since had some changes to several aspects of Django, Postgres, Apache, and a pull from Github. In addition, it has been some time since those changes were made and I don't recall or can't track every change that may be causing the problem.

I get the message when I run python manage.py runserver or any other python manage.py ... command except python manage.py check, which states the system is good.

up vote 73 down vote accepted favorite
沙发
+730
+50

我能夠根據問題基本上,需要將postgres特權重新授予db用戶。就我而言,那是我在虛擬環境設置文件中設置的用戶。從命令行(或postgres)運行以下命令,其中 mydatabase dbuser 應該是您自己的數據庫和用戶名:

  psql mydatabase -c“在SCHEMA public to dbuser的所有表格中全部授予;” psql mydatabase -c“在SCHEMA public to dbuser中對所有序列進行全部授權;” psql mydatabase -c“
     
			
        

哇,謝謝你!一直在尋找解決方案。當我已經遷移了數據庫然後我嘗試設置geodjango時,我遇到了這個問題。 - qasimalbaqali '17年3月9日22:35

當我用一個用戶創建數據庫然後更改數據庫的所有者時,我遇到此問題。這些表保留了舊所有者導致此錯誤的原因。修復我刪除了數據庫,使用posgres用戶重新創建它,為新用戶授予所有權限並運行遷移。 - 壁虎於18年3月24日18:20

我不知道怎麼做,更容易重新創建整個數據庫=) - geckos 4月2日'18在19:57

關於在Saleor上安裝Saleor的Saleor官方文檔的人可能需要這個答案。我做到了。 - Rik Schoonbeek 3月8日19:27

+20
<p>如@ user3062149所述,這可能是由於嘗試遷移Django的psycopg2用戶不是表所有者的數據庫表而引起的。例如,如果你的項目有<code> settings.py </ code> </ p> <pre> <code> DATABASES = {'default':{'USER':'my_username',#... < / code> </ pre> <p>您需要檢查Django遷移中涉及的表是否由<code> my_username </ code>所有。要在<code> psql </ code>中執行此操作,可以使用<code> SELECT * FROM pg_tables ORDER BY tableowner; </ code>。這使用視圖<a href="https://www.postgresql.org/docs/current/static/view-pg-tables.html" rel="nofollow noreferrer"> <code> pg_tables </ code> < / a>,“提供對數據庫中每個表的有用信息的訪問”。<code> pg_tables </ code>是Postgres的<a href="https://www.postgresql.org/docs/current/static/catalogs.html" rel="nofollow noreferrer"> <em>系統的一部分目錄</ em> </a>,即關係數據庫管理系統存儲模式元數據的位置。</ p> <p>假設有問題的表歸<code> other_username </ code>所有(不是<code > my_username </ code>)。</ p> <p>要更新所有者,您需要使用<code> - username = other_username </ code>調用<code> psql </ code>,然後更改所有者:</ p> <pre> <code> ALTER TABLE public。&lt; table_name&gt; 所有者都是my_username; </代碼> </ PRE>
89
votes
answers
11 views
+10

How to list custom types using Postgres information_schema

I am trying to find the equivalent SQL of dT using the information_schema and can't seem to find anything. Does such a thing exist?

Example: If I add the following custom type enum, how can I see it in the information_schema?

CREATE TYPE communication.channels AS ENUM
   ('text_message',
    'email',
    'phone_call',
    'broadcast');

NOTE: I do have the exact SQL used by dT (retrieved by turning up the logging) but I am looking specifically for a cleaner implementation using the information_schema

沙发
+80
+50

枚舉不在SQL標準中,因此未在信息架構中表示。其他用戶定義的類型通常位於視圖 user_defined_types 中,但未實現。所以目前,您無法使用信息模式在PostgreSQL中列出用戶定義的類型。

+430

供參考,這裡是來自dT的SQL(pgAdmin使用相同或類似的)

  SELECT n.nspname作為模式,t.typname作為類型FROM pg_type t LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE(t.typrelid = 0 OR(SELECT c.relkind ='c'FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))AND NOT EXISTS(SELECT 1 FROM pg_catalog。 pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)AND n.nspname NOT IN('pg_catalog','information_schema') 
     
			
        

此代碼顯示所有類型的列表,包括用戶定義的枚舉,但不提供有關如何定義它們的詳細信息。 - Eliyahu Skoczylas 17年5月5日14:05

+180

這是列出當前數據庫中所有枚舉定義類型的簡單方法。查詢結果返回兩列,第一列顯示每個枚舉類型的名稱,第二列顯示每個枚舉類型的每個值的名稱:

  SELECT pg_type.typname AS enumtype,pg_enum.enumlabel AS enumlabel FROM pg_type JOIN pg_enum ON pg_enum.enumtypid = pg_type.oid;  
     
			
        

AS enumlabel部分是多餘的,你不覺得嗎? - Pere於2017年2月15日15:38

我想,這應該是一個正確的答案--Alex Sham 4月16日22:59

+90

列出所有數據庫類型:

  test =#dT數據類型列表Schema | 名稱| 說明-------- + --------------------- + ------------- public | 性別| 公眾| 狀態|   

列出所有數據庫類型以及值等附加信息:

  test =#dT +數據類型列表Schema | 名稱| 內部名稱| 尺寸| 元素| 所有者| 訪問權限| 說明-------- + --------------------- + ------------------ --- + ------ + ------------------- ------- + + ----------- -------- + -------------公開| 性別| 性別| 4 | 男+ 瓦迪姆| | | | | | 女性| | | 公眾| 狀態| 狀態| 4 | 處理+ | 瓦迪姆| | | | | | 傳遞+ | | | | | | | 失敗了| | |   

獲取具有附加信息的特定類型:

  leps =#dT + gender數據類型列表Schema | 名稱| 內部名稱| 尺寸| 元素| 所有者| 訪問權限| 說明-------- + ------------ + --------------- + ------ + ---- --------------- + ------- + ------------------- + ------ -------公眾| 性別| 性別| 4 | 男+ 瓦迪姆| | | | | | 女+ | |   leps =#dT + gender數據類型列表Schema | 名稱| 內部名稱| 尺寸| 元素| 所有者| 訪問權限| 說明-------- + ------------ + --------------- + ------ + ---- --------------- + ------- + ------------------- + ------ -------公眾| 性別| 性別| 4 | 男+ 瓦迪姆| | | | | | 女+ | |   leps =#dT + gender數據類型列表Schema | 名稱| 內部名稱| 尺寸| 元素| 所有者| 訪問權限| 說明-------- + ------------ + --------------- + ------ + ---- --------------- + ------- + ------------------- + ------ -------公眾| 性別| 性別| 4 | 男+ 瓦迪姆| | | | | | 女+ | |  
     
			
        
+80

您的自我類型定義的所有列表:

  dT testDB =&gt; dT數據類型列表Schema | 名稱| 說明-------- + ------------------------- + -------------公開| myType | (1行) 
     
			
        
+30

我使用視圖來顯示我的枚舉名稱。因此,該視圖中的數據可以在應用程序中使用,以提供枚舉字段的可用選項列表。

 創建或替換視圖vw_enums AS SELECT t.typname,e.enumlabel,e .enumsortorder FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid;  
     
			
        
0

請看這裡: http:// www。 postgresql.org/docs/current/static/catalog-pg-enum.html

pg_enum目錄應該包含您正在查找的數據

不幸的是,pg_enum目錄只包含枚舉標籤,而不包含架構或其他任何內容。所以你必須做一個連接才能得到有意義的數據 - Collin Peters 2010年9月13日19:29

0
votes
answers
22 views
+10

錯誤的計算由用戶定義的SQL函數

1

我有一個功能,通過錯誤的計算由用戶定義的SQL函數

CREATE OR REPLACE FUNCTION public.div(dividend INTEGER, divisor INTEGER) 
    RETURNS INTEGER 
    LANGUAGE 'sql' 
    IMMUTABLE 
    LEAKPROOF 
    STRICT 
    SECURITY DEFINER 
    PARALLEL SAFE 
    AS $BODY$ 
     SELECT ($1 + $2/2)/$2; 
    $BODY$; 

應該算一個商業四捨五入的結果確定。大多數情況下,它完成這項工作。我不知道爲什麼,但select div(5, 3)給了我正確的答案,而當一個參數通過聚合來計算時,例如select div(5, 3)select div(sum(val), 3) from (select 1 as val UNION SELECT 4) list足以觸發這一點。 我該如何修復div?我不想投入每一個輸入。

順便說一下,使用SELECT (cast($1 as integer) + cast($2 as integer)/2)/cast($2 as integer);作爲div的定義沒有幫助。

沙发
0
1

更改函數的名稱。

功能div(numeric, numeric)是一個內建的Postgres功能,有你要調用其功能的歧義:

select div(5, 3)   -- calls your function public.div(integer, integer) 
select div(5::bigint, 3) -- calls pg_catalog.div(numeric, numeric) 

在第二種情況下的參數必須解決和系統功能被選爲第一。

請注意,函數sum(integer)給出bigint作爲結果。

+0

太糟糕了,我沒有想到這一點。謝謝。 – Bolpat

板凳
0
1

允許浮點數作爲參數,然後在計算時顯式強制轉換,否則在傳遞參數時有隱式轉換。

CREATE OR REPLACE FUNCTION my_div(dividend FLOAT, divisor FLOAT) 
    RETURNS INTEGER 
    LANGUAGE 'sql' 
    IMMUTABLE 
    -- LEAKPROOF -- not allowed at dbfiddle.uk 
    STRICT 
    SECURITY DEFINER 
    PARALLEL SAFE 
    AS $BODY$ 
     SELECT --($1 + $2/2)/$2; 
      (cast($1 as integer) + cast($2 as integer)/2)/cast($2 as integer) 
    $BODY$; 
 
? 
select my_div(sum(val), 3) 
from (select 1 as val UNION SELECT 4) x 
 
| my_div | 
| -----: | 
|  2 | 

dbfiddle here

0
votes
answers
19 views
+10

PostgreSQL的選擇*,其中列包含數組值

0

我有一個PostgreSQL數據庫這樣的:PostgreSQL的選擇*,其中列包含數組值

users 
id  name  companyrestrictions 
1  Bill  [3, 4] 
2  Fred  [5, 6] 

然後爲每個公司3變量在這種情況下

所以我寫了這樣的查詢:

SELECT * FROM users WHERE 3 = ANY(users.companyrestrictions)

但我發現了以下錯誤: OP任何/所有(陣列)要求在右側

公司限制數組類型的jsonb

我在做什麼錯?

+0

由於錯誤提示:您不能在JSONB列上使用數組運算符。沒有用於測試JSONB列內數組內的元素的等價函數。如果你想存儲的只是一個數組,那你爲什麼不使用數組? –

+0

我沒有看到Postgres的數組數據類型,有沒有一個?這叫什麼? – Jordash

+0

https://www.postgresql.org/docs/current/static/arrays.html –

沙发
0
3

嘗試<@包括operator

<@ Are the left JSON path/value entries contained at the top level within the right JSON value?

SELECT * FROM users WHERE '3' <@ users.companyrestrictions 

任何只適用於陣列

+0

返回這個錯誤:'操作符不存在:integer <@ jsonb' – Jordash

+0

奇怪 - ''3''不是整數.. –

+0

你是對的,我沒有注意到你把3變成了一個字符串,它現在可以工作,即使你有這樣一個數組''[3,33,333]''這樣的數組嗎? – Jordash

板凳
0
1

這可能是更好的存儲公司限制另一個表。 這正是RDBMS的用途。

如果你真的需要使用JSON,你可能需要解析它。在postgres中可能會有一些JSON函數可用,但對數組來說似乎很麻煩,並且您將無法使用SQL查詢數據。

CREATE TABLE t_user (
    id SERIAL     PRIMARY KEY NOT NULL, 
    name CHARACTER VARYING(256) NOT NULL 
); 

CREATE UNIQUE INDEX t_user_idx ON t_users(name); 

CREATE TABLE t_company (
    id SERIAL     PRIMARY KEY NOT NULL, 
    name CHARACTER VARYING(256) NOT NULL 
); 

CREATE UNIQUE INDEX t_company_idx ON t_company(name); 

CREATE TABLE t_company_restriction (
    id   SERIAL PRIMARY KEY NOT NULL, 
    id_company integer NOT NULL REFERENCES t_company(id) ON DELETE CASCADE, 
    id_user integer NOT NULL REFERENCES t_user(id) ON DELETE CASCADE 
); 

CREATE UNIQUE INDEX t_company_restriction_idx ON t_company_restriction(id_company, id_user); 

INSERT INTO t_user(name) VALUES ('Bill'); 
INSERT INTO t_user(name) VALUES ('Fred'); 

INSERT INTO t_company (name) VALUES ('Company 1'); 
INSERT INTO t_company (name) VALUES ('Company 2'); 
INSERT INTO t_company (name) VALUES ('Company 3'); 
INSERT INTO t_company (name) VALUES ('Company 4'); 

INSERT INTO t_company_restriction (id_user, id_company) 
SELECT u.id, c.id FROM t_user u, t_company c 
WHERE u.name = 'Bill' AND c.name = 'Company 1'; 

INSERT INTO t_company_restriction (id_user, id_company) 
SELECT u.id, c.id FROM t_user u, t_company c 
WHERE u.name = 'Bill' AND c.name = 'Company 2'; 

INSERT INTO t_company_restriction (id_user, id_company) 
SELECT u.id, c.id FROM t_user u, t_company c 
WHERE u.name = 'Fred' AND c.name = 'Company 3'; 

INSERT INTO t_company_restriction (id_user, id_company) 
SELECT u.id, c.id FROM t_user u, t_company c 
WHERE u.name = 'Fred' AND c.name = 'Company 4'; 

SELECT u.name 
FROM t_user u, t_company c, t_company_restriction cr 
WHERE c.name = 'Company 1' 
AND c.id = cr.id_company 
AND u.id = cr.id_user; 
0
votes
answers
11 views
+10

爲什麼我不能在我的節點應用程序中重命名這個對象?

0

我有一個node.js/express應用程序使用node-postgres模塊與Postgres數據庫進行通信。它正在處理異步/等待,但是如果我將對象重命名爲{rows}以外的任何其他對象,則會返回undefined。這是我的代碼;注意右下async和註釋,上面const { rows } = ...爲什麼我不能在我的節點應用程序中重命名這個對象?

var express = require('express'); 
var router = express.Router(); 

const { Pool } = require('pg'); 
const pool = new Pool({ 
    connectionString: 'postgresql://[email protected]/mydb' 
}); 

router.post('/login', function(req, res, next) { 
    var username = req.body.username; 
    var password = req.body.password; 

    (async() => { 
    // if I rename this from "rows" to, say, "userdetails", it comes back undefined 
    const { rows } = await pool.query(` 
      SELECT id, password 
      FROM myschema.users 
      WHERE username = $1 
      LIMIT 1;`,[username]); 

    if (rows.length) { 
     // check password, etc, etc. 
     return res.status(200).send(); 
    } else { 
     return res.status(401).send(); 
    }  
    })().catch(e => setImmediate(() => { 
    res.status(500); 
    } 
)); 

}); 

module.exports = router; 

我敢肯定,我想的東西很基本在這裏,但我爲什麼不能重命名此? pg模塊是否指定返回的var/const必須命名爲{ rows }?如果是這樣,我怎麼會發現?我在await處設置了一個斷點並逐步完成代碼,但對我而言仍然不清楚。

+0

以防萬一,你重命名的所有實例行變量到你的新變量名? – Alan

沙发
0
1

當您執行const { rows } = xxx時,您正在使用object destructing將??3210屬性分配給本地作用域中與該屬性具有相同名稱的新變量。

因此,當您更改屬性的名稱到別的東西:

const { myVar } = xxx; 

代碼正在尋找合適的物業xxx.myVar這可能不存在,因此最終undefined

如果要使用不同的名稱,則必須使用不同形式的對象解構賦值(包括新名稱),或者根本不使用解構並僅將.rows屬性分配給新的變量。

例如,你可以這樣做,而不是:

const result = await pool.query(` 
      SELECT id, password 
      FROM myschema.users 
      WHERE username = $1 
      LIMIT 1;`,[username]); 

const myVar = result.rows; 

或者你可以在對象解構賦值指定一個新的名字:

const {rows: myVar} = await pool.query(` 
      SELECT id, password 
      FROM myschema.users 
      WHERE username = $1 
      LIMIT 1;`,[username]); 

console.log(myVar); 
+0

謝謝。列出替代方案非常有幫助。 – rotarydial

板凳
0
1

這叫做。當你做這樣的事情

const { row } = someObject 

那麼變量row等於row property of someObject。但如果someObject甚至沒有任何row財產,那麼row明顯將爲undefined

你的情況也是如此。 await pool.query(...返回的對象有rows屬性,這就是爲什麼const { rows }有效,但它沒有userdetails屬性,因此undefined

67
votes
answers
10 views
+10

Understanding postgres explain w/ bitmap heap/index scans

I have a table w/ 4.5 million rows. There is no primary key. The table has a column p_id, type integer. There's an index, idx_mytable_p_id on this column using the btree method. I do:

SELECT * FROM mytable WHERE p_id = 123456;

I run an explain on this and see the following output:

Bitmap Heap Scan on mytable  (cost=12.04..1632.35 rows=425 width=321)
  Recheck Cond: (p_id = 543094)
  ->  Bitmap Index Scan on idx_mytable_p_id  (cost=0.00..11.93 rows=425 width=0)
        Index Cond: (p_id = 543094)

Questions:

  • Why is that query doing a heap scan and then a bitmap index scan?
  • Why is it examining 425 rows? Why is the width of the operation 321?
  • What is the cost of 12.04..1632.35 and 0.00..11.93 telling me?

For the record there are 773 rows with the p_id value of 123456. There are 38 columns on mytable.

Thanks!

up vote 54 down vote accepted favorite
沙发
+540
+50

為什麼該查詢執行堆掃描然後進行位圖索引掃描?

這不是,確切地說。EXPLAIN輸出顯示執行節點的結構,其中“更高”級別(不縮進)從它們下面的節點中拉出行。因此,當位圖堆掃描節點轉到第一行時,位圖索引掃描會運行以確定要使用的行集,並將第一行的信息傳遞給堆掃描。索引掃描傳遞索引以確定需要讀取哪些行,堆掃描實際讀取它們。這個想法是通過從頭到尾而不是按索引順序讀取堆,它將減少隨機訪問 - 當加載該頁面時,將讀取給定頁面中的所有匹配行,並且可以讀取足夠多的頁面以便使用更便宜的順序訪問,而不是在整個磁盤上來回搜索。

為什麼要檢查425行? < p>不是。您運行了EXPLAIN,它只顯示您的估計值和所選擇的計劃,它根本不會檢查行。與運行EXPLAIN ANALYZE相比,EXPLAIN的值相當有限,實際上運行查詢並顯示估計和實際的數字。

為什麼操作321的寬度?

顯然是 mytable 中元組的大小(以字節為單位)。

12.04的成本是多少.. 1632.35和0.00..11.93告訴我?

第一個數字是從該節點返回第一行的成本; 第二個數字是返回該節點的所有行的開銷。請記住,這些都是估算值。該單位是一個抽象成本單位。絕對數字沒什麼意義; 規劃中最重要的是哪個計劃的成本最低。如果您使用光標,則第一個數字很重要; 否則通常是第二個數字。(我認為它會為LIMIT子句進行插值。)

通常需要調整可配置的成本因子,例如 random_page_cost cpu_tuple_cost ,以便準確模擬環境中的成本。如果沒有這樣的調整,比較成本可能與相應的運行時間不匹配,

內部操作的總成本將始終包含在外部操作的啟動成本中。 - vyegorov 12年12月13日20:08

@vyegorov是對的,但需要注意的是,對於來自EXPLAIN ANALYZE的實際數據,您應該了解節點所花費的總時間除以循環以顯示每次迭代的時間。正如您所料,它是包含在封閉節點中的節點的總時間。 - kgrittn 12年12月13日20:24

+130

重新1)必須從最內層節點到最外層節點讀取執行計劃。所以它首先進行索引掃描(查找行)並訪問實際表以返回索引掃描找到的行

重新計算2)計劃中顯示的行數只是基於估計的在統計數據和425與773聽起來相當合理。如果您想查看真實數字,請使用 explain analyze

重新3)成本數字中的第一個數字是初始化的“啟動”成本規劃人員的步驟,第二個成本是該步驟的總成本。

這些都記錄在手冊中: http:

0
votes
answers
26 views
+10

在postgresql中包含/ in文本數組的Hibernate條件

0

我有一個名爲box的實體。每個包含一些參數的參數對於許多唯一的ID都是相同的。唯一ID只是數字,並沒有任何其他角色。 所以我創建它們作爲postgresql和Java中的文本數組,我將它們作爲ArrayList並使用自定義用戶類型進行映射。 package com.geniedoc.utils;在postgresql中包含/ in文本數組的Hibernate條件

import java.io.Serializable; 
import java.sql.Array; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Types; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Iterator; 
import java.util.List; 
import java.util.StringTokenizer; 
import org.hibernate.HibernateException; 
import org.hibernate.engine.spi.SessionImplementor; 
import org.hibernate.usertype.UserType; 

public class PostgresTextArrayType implements UserType { 

    protected static final int[] SQL_TYPES = {Types.ARRAY}; 
    public Class<String> returnedClass() { 
      return String.class; 
     } 

    public final int[] sqlTypes() { 
      return SQL_TYPES; 
     } 


     @Override 
     public Object nullSafeGet(ResultSet resultSet, String[] names, 
       SessionImplementor arg2, Object arg3) 
       throws HibernateException, SQLException { 
      List<String> list = null; 
      String nameVal = resultSet.getString(names[0]); 
      if (nameVal != null) { 
       nameVal = nameVal.substring(1,nameVal.length()-1); 
       list = new ArrayList<>(); 
       StringTokenizer tokenizer = new StringTokenizer(nameVal, ","); 
       while (tokenizer.hasMoreElements()) { 
        String val = (String) tokenizer.nextElement(); 
        list.add(val); 
       } 
      } 

      return list; 

     } 

     @Override 
     public void nullSafeSet(PreparedStatement statement, Object value, int index, 
       SessionImplementor arg3) throws HibernateException, 
       SQLException { 
      Connection connection = statement.getConnection(); 
       if (value == null) { 
        statement.setNull(index, SQL_TYPES[0]); 
       } else { 
        System.out.println("statement>>>>"+statement); 
        System.out.println("value>>>>"+ value); 
        System.out.println("index>>>>"+index); 
        @SuppressWarnings("unchecked") 
        ArrayList<String> parameter=new ArrayList<>(); 
        if(value instanceof Array) 
        { parameter=(ArrayList<String>) value; 
        }else 
        { 
         parameter.add((String) value); 
        } 
        ArrayList<String> list=parameter; 
        String[] castObject = Arrays.copyOf(list.toArray(), list.toArray().length, String[].class); 
        Array array = connection.createArrayOf("text", castObject); 
        statement.setArray(index, array); 
        System.out.println("statement>>>>"+statement); 
       } 
     } 
     @Override 
     public final Object deepCopy(final Object value) throws HibernateException { 
      return value; 
     } 

     @Override 
     public final boolean isMutable() { 
      return false; 
     } 

     @Override 
     public final Object assemble(final Serializable serializable, final Object arg1) 
       throws HibernateException { 
      return serializable; 
     } 

     @Override 
     public final Serializable disassemble(final Object o) throws HibernateException { 
      return (Serializable) o; 
     } 

     @Override 
     public final boolean equals(final Object x, final Object y) throws HibernateException { 
      if (x == y) { 
       return true; 
      } else if (x == null || y == null) { 
       return false; 
      } else { 
       return x.equals(y); 
      } 
     } 

     @Override 
     public final int hashCode(final Object x) throws HibernateException { 
      return x.hashCode(); 
     } 

     @Override 
     public final Object replace(
      final Object original, 
      final Object target, 
      final Object owner) throws HibernateException { 
      return original; 
     } 
      private String serialize(List<String> list) { 
       StringBuilder strbul = new StringBuilder(); 
       Iterator<String> iter = list.iterator(); 
       strbul.append("{"); 
       while (iter.hasNext()) { 
        strbul.append(iter.next()); 
        if (iter.hasNext()) { 
         strbul.append(","); 
        } 
       } 
       strbul.append("}"); 
       return strbul.toString(); 
      } 


} 

這是我的休眠條件: -

Session session=getSession(); 
    Criteria criteria=session.createCriteria(Box.class); 
    criteria.add(Restrictions.in("unique_id", unique_id)); 
    return (Unit)criteria.uniqueResult(); 

我需要包含一個特定的獨特id.But它不工作的框。 僅當我在數據庫中的文本數組中有一個值時才返回結果。 但是,如果我有在數據庫中的多個值,它不顯示任何結果。

任何幫助表示讚賞。

沙发
0
0

實施UserType通常是不值得的。由於Postgres接受數組的字符串格式,因此將類型@PrePersist,??和@PostLoad函數添加到您的類中會更好。由於它只是數字,所以轉換非常簡單。

@Transient 
private long[] theids; 

@Column(name = "the_ids") 
private String therealids; 

@PrePersist 
@PreUpdate 
private void encode() { 
    therealids = "{" + java.util.Arrays.toString(theids) + "}"; 
} 

@PostLoad 
private void decode() { 
    String[] ids = therealids.split(","); 
    theids = new long[ids.length]; 
    if (ids.length == 0) { 
     return; 
    } 
    int last = ids.length - 1; 
    // remove the "{" 
    ids[0] = ids[0].substr(1); 
    // remove the "}" 
    ids[last] = ids[last].substr(0, ids[last].length() - 1); 
    for (int i = 0; i < ids.length; i++) theids[i] = Long.parseLong(ids[i]); 
} 

至少有4個優化你可以做這個代碼,使其速度更快,更少的內存大戶,但這是短版。

如果您想要做同樣的事情,但是對於字符串數組,您必須非常瞭解該場景中陣列的正確轉義語法,更糟糕的是,可選的雙引號。

0
votes
answers
22 views
+10

查詢一個大的Postgres相關表

1

我有一個大的Postgres表(150GB +),它在兩個變量val1和val2之間存儲一個大的相關矩陣。例如:查詢一個大的Postgres相關表

val1 | val2 | distance 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    0 | 1 |  10 
    0 | 2 |  21 
    0 | 3 |  13 
    1 | 2 |  65 
    1 | 3 |  43 
    2 | 3 |  56 

對(val1,val2)是表的複合主鍵。我發現當我在下面運行查詢時,查詢在35ms以下執行。

SELECT * 
FROM sliding_window_distances 
WHERE (val1 = 10000) 

但是,當我使用val2進行搜索時,它不會執行並超時。

SELECT * 
FROM sliding_window_distances 
WHERE (val2 = 10000) 

理想我想運行下面的查詢,讓我對特定值的所有記錄(10000在我的例子)

SELECT * 
FROM sliding_window_distances 
WHERE (val1 = 10000) 
OR (val2 = 10000) 

我不知道如何加快查詢。

+0

添加額外的UNIQUE約束(val2,val1)。 (這將創建一個索引) – wildplasser

沙发
0
1

在執行導致超時的任何其他操作之前,您可能需要清理陳舊的緩存數據。

第一式:

VACUUM ANALYZE sliding_window_distances; 

而且你應該在你的表使用二級索引。顯着創建索引加速的查詢操作。

要沒有鎖定了創建索引寫入表:

CREATE INDEX CONCURRENTLY windows_dist_index ON sliding_window_distances (val2); 

您也可以定義附加UNIQUE約束象下面這樣:

ALTER TABLE sliding_window_distances ADD UNIQUE (val2, val1); 

PostgreSQL Documentation on Indexes

+0

嗨GökcanD,謝謝..創建索引似乎超時...表是非常大的。 – kPow989

+0

@ kPow989是否有任何我們可以看到的錯誤日誌?另外,請嘗試「真空」解決方案。 – gokcand

+0

謝謝..組合鍵(val1,val2)已經是唯一的......創建索引時我只是得到一個超時值。我讀過它們也可能需要幾小時才能完成。 – kPow989