Warn against pre-existing indexes.

Pre-existing indexes will reduce data loading performances and it's
generally better to DROP the index prior to the load and CREATE them
again once the load is done. See #251 for an example of that.

In that patch we just add a WARNING against the situation, the next
patch will also add support for a new WITH clause option allowing to
have pgloader take care of the DROP/CREATE dance around the data
loading.
This commit is contained in:
Dimitri Fontaine 2015-07-16 00:36:40 +02:00
parent 81ad98b323
commit 7c834db6e3
4 changed files with 47 additions and 9 deletions

View File

@ -178,6 +178,7 @@
#:list-databases
#:list-tables
#:list-columns
#:list-indexes
#:list-tables-cols
#:list-tables-and-fkeys
#:list-reserved-keywords
@ -244,6 +245,8 @@
(:use #:cl
#:pgloader.params #:pgloader.utils #:pgloader.connection
#:pgloader.sources #:pgloader.queue)
(:import-from #:pgloader.pgsql
#:list-indexes)
(:export #:*csv-path-root*
#:csv-connection
#:specs

View File

@ -189,6 +189,31 @@
where c.oid = '~:[~*~a~;~a.~a~]'::regclass and attnum > 0
order by attnum" schema schema table-name) :column)))
(defun list-indexes (pgconn table-name)
"List all indexes for TABLE-NAME in SCHEMA."
(with-pgsql-connection (pgconn)
(loop :for (index-name table-name table-oid primary sql)
:in (pomo:query (format nil "
select i.relname,
indrelid::regclass,
indrelid,
indisprimary,
pg_get_indexdef(indexrelid)
from pg_index x
join pg_class i ON i.oid = x.indexrelid
where indrelid = '~@[~a.~]~a'::regclass"
(when (typep table-name 'cons)
(car table-name))
(typecase table-name
(cons (cdr table-name))
(string table-name))))
:collect (make-pgsql-index :name index-name
:table-name table-name
:table-oid table-oid
:primary primary
:columns nil
:sql sql))))
(defun list-reserved-keywords (pgconn)
"Connect to PostgreSQL DBNAME and fetch reserved keywords."
(handler-case

View File

@ -263,7 +263,7 @@
;;;
;;; Index support
;;;
(defstruct pgsql-index name table-name table-oid primary unique columns)
(defstruct pgsql-index name table-name table-oid primary unique columns sql)
(defgeneric index-table-name (index)
(:documentation
@ -293,18 +293,20 @@
(values
;; ensure good concurrency here, don't take the ACCESS EXCLUSIVE
;; LOCK on the table before we have the index done already
(format nil "CREATE UNIQUE INDEX ~a ON ~a (~{~a~^, ~});"
index-name table-name cols)
(or (pgsql-index-sql index)
(format nil "CREATE UNIQUE INDEX ~a ON ~a (~{~a~^, ~});"
index-name table-name cols))
(format nil
"ALTER TABLE ~a ADD PRIMARY KEY USING INDEX ~a;"
table-name index-name)))
(t
(format nil "CREATE~:[~; UNIQUE~] INDEX ~a ON ~a (~{~a~^, ~});"
(pgsql-index-unique index)
index-name
table-name
cols)))))
(or (pgsql-index-sql index)
(format nil "CREATE~:[~; UNIQUE~] INDEX ~a ON ~a (~{~a~^, ~});"
(pgsql-index-unique index)
index-name
table-name
cols))))))
;;;
;;; Parallel index building.

View File

@ -179,7 +179,15 @@
(*state* (or *state* (pgloader.utils:make-pgstate)))
(lp:*kernel* (make-kernel 2))
(channel (lp:make-channel))
(queue (lq:make-queue :fixed-capacity *concurrent-batches*)))
(queue (lq:make-queue :fixed-capacity *concurrent-batches*))
(indexes (list-indexes (target-db csv)
(target csv))))
;; issue a performance warning against pre-existing indexes
(when indexes
(log-message :warning "Target table ~s has ~d indexes defined against it."
(target csv) (length indexes))
(log-message :warning "That could impact loading performance badly"))
(with-stats-collection ((target csv)
:dbname (db-name (target-db csv))