PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL:Làm thế nào để lập chỉ mục tất cả các khóa ngoại?

CHỈNH SỬA :vì vậy, tôi đã viết truy vấn dưới đây và sau đó nghĩ rằng ... "chờ đã, Postgresql yêu cầu các mục tiêu khóa ngoài phải có các chỉ số duy nhất." Vì vậy, tôi đoán tôi đã hiểu sai ý của bạn? Bạn có thể sử dụng truy vấn bên dưới để kiểm tra xem nguồn trong số các khóa ngoại của bạn có các chỉ mục bằng cách thay thế "conrelid" cho "confrelid" và "conkey" cho "confkey" (vâng, vâng, không có bí danh trong truy vấn ...)

Chà, tôi đoán có thể xem qua danh mục hệ thống ... Như thường lệ, hướng dẫn tốt nhất về danh mục hệ thống là sử dụng psql và thực hiện "\ set ECHO_HIDDEN 1", sau đó xem SQL mà nó tạo ra có gì thú vị "\ lệnh d ”. Đây là SQL được sử dụng để tìm khóa ngoại cho một bảng ("\ d tablename"):

-- $1 is the table OID, e.g. 'tablename'::regclass
SELECT conname, conrelid::pg_catalog.regclass,
  pg_catalog.pg_get_constraintdef(c.oid, true) as condef
FROM pg_catalog.pg_constraint c
WHERE c.confrelid = $1 AND c.contype = 'f' ORDER BY 1;

Có vẻ như pg_constraint có các cột conkeyconfkey trông giống như chúng có thể là số cột mà khóa được xác định trên đó. Có thể là confkey là số cột trong bảng ngoại vì nó chỉ khác rỗng đối với khóa ngoại. Ngoài ra, tôi phải mất một lúc để nhận ra đây là SQL để hiển thị khóa ngoại tham chiếu bảng đã cho. Đó là những gì chúng tôi muốn.

Vì vậy, một cái gì đó truy vấn này cho thấy dữ liệu bắt đầu hình thành:

select confrelid, conname, column_index, attname
from pg_attribute
     join (select confrelid::regclass, conname, unnest(confkey) as column_index
           from pg_constraint
           where confrelid = 'ticket_status'::regclass) fkey
          on fkey.confrelid = pg_attribute.attrelid
             and fkey.column_index = pg_attribute.attnum

Tôi sẽ sử dụng 8.4 tính năng như unnest ... bạn có thể hòa nhập mà không cần.

Tôi đã kết thúc với:

select pg_index.indexrelid::regclass, 'create index ' || relname || '_' ||
         array_to_string(column_name_list, '_') || '_idx on ' || confrelid ||
         ' (' || array_to_string(column_name_list, ',') || ')'
from (select distinct
       confrelid,
       array_agg(attname) column_name_list,
       array_agg(attnum) as column_list
     from pg_attribute
          join (select confrelid::regclass,
                 conname,
                 unnest(confkey) as column_index
                from (select distinct
                        confrelid, conname, confkey
                      from pg_constraint
                        join pg_class on pg_class.oid = pg_constraint.confrelid
                        join pg_namespace on pg_namespace.oid = pg_class.relnamespace
                      where nspname !~ '^pg_' and nspname <> 'information_schema'
                      ) fkey
               ) fkey
               on fkey.confrelid = pg_attribute.attrelid
                  and fkey.column_index = pg_attribute.attnum
     group by confrelid, conname
     ) candidate_index
join pg_class on pg_class.oid = candidate_index.confrelid
left join pg_index on pg_index.indrelid = confrelid
                      and indkey::text = array_to_string(column_list, ' ')

OK, sự quái dị này in ra các lệnh chỉ mục ứng viên và cố gắng khớp chúng với các chỉ số hiện có. Vì vậy, bạn có thể chỉ cần thêm "nơi indexrelid là null" ở cuối để nhận các lệnh tạo chỉ số dường như không tồn tại.

Truy vấn này không xử lý tốt các khóa ngoại nhiều cột; nhưng imho nếu bạn đang sử dụng những thứ đó, bạn xứng đáng gặp rắc rối.

CHỈNH SỬA SAU :đây là truy vấn với các chỉnh sửa được đề xuất ở trên cùng được đưa vào. Vì vậy, điều này hiển thị các lệnh để tạo các chỉ mục không tồn tại, trên các cột là nguồn của khóa ngoại (không phải mục tiêu của nó).

select pg_index.indexrelid::regclass, 'create index ' || relname || '_' ||
         array_to_string(column_name_list, '_') || '_idx on ' || conrelid ||
         ' (' || array_to_string(column_name_list, ',') || ')'
from (select distinct
       conrelid,
       array_agg(attname) column_name_list,
       array_agg(attnum) as column_list
     from pg_attribute
          join (select conrelid::regclass,
                 conname,
                 unnest(conkey) as column_index
                from (select distinct
                        conrelid, conname, conkey
                      from pg_constraint
                        join pg_class on pg_class.oid = pg_constraint.conrelid
                        join pg_namespace on pg_namespace.oid = pg_class.relnamespace
                      where nspname !~ '^pg_' and nspname <> 'information_schema'
                      ) fkey
               ) fkey
               on fkey.conrelid = pg_attribute.attrelid
                  and fkey.column_index = pg_attribute.attnum
     group by conrelid, conname
     ) candidate_index
join pg_class on pg_class.oid = candidate_index.conrelid
left join pg_index on pg_index.indrelid = conrelid
                      and indkey::text = array_to_string(column_list, ' ')
where indexrelid is null

Kinh nghiệm của tôi là điều này không thực sự hữu ích. Nó gợi ý tạo chỉ số cho những thứ như mã tham chiếu thực sự không cần lập chỉ mục.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Không thể tạo vai trò PostgreSQL Superuser để cài đặt và chạy Ứng dụng

  2. Mô phỏng TẠO CƠ SỞ DỮ LIỆU NẾU KHÔNG TỒN TẠI cho PostgreSQL?

  3. Thư viện không được tải:/usr/local/lib/libpq.5.4.dylib

  4. Thay đổi đối chiếu cơ sở dữ liệu, Ctype trong Postgresql

  5. PSQLException:Tập kết quả này đã bị đóng