diff --git a/src/metabase/driver/generic_sql.clj b/src/metabase/driver/generic_sql.clj index 2a99c567c0071c01c4cee9395d71ae679c120574..cb7e81d795382030e5e2f1df07fc56c3b0c8c11d 100644 --- a/src/metabase/driver/generic_sql.clj +++ b/src/metabase/driver/generic_sql.clj @@ -125,12 +125,20 @@ (let [~binding (.getMetaData conn#)] ~@body))) -(defn- active-tables [driver database] +(defn- active-tables + "Fast implementation of `IDriver/active-tables`. + Fetches list of schemas, then for each one not in `excluded-schemas`, fetch their Tables. + + The old implementation fetched *all* Tables, then filtered out ones with `excluded-schemas` in Clojure; + this is as much as 15x faster for Databases with a lot of system tables like Oracle (4 seconds vs 60)." + [driver database] (with-metadata [md driver database] - (set (for [table (filter #(not (contains? (excluded-schemas driver) (:table_schem %))) - (jdbc/result-set-seq (.getTables md nil nil nil (into-array String ["TABLE", "VIEW"]))))] - {:name (:table_name table) - :schema (:table_schem table)})))) + (let [all-schemas (set (map :table_schem (jdbc/result-set-seq (.getSchemas md)))) + schemas (set/difference all-schemas (excluded-schemas driver))] + (set (for [schema schemas + table-name (mapv :table_name (jdbc/result-set-seq (.getTables md nil schema nil (into-array String ["TABLE", "VIEW"]))))] + {:name table-name + :schema schema}))))) (defn- active-column-names->type [driver table] (with-metadata [md driver @(:db table)] diff --git a/src/metabase/driver/sync.clj b/src/metabase/driver/sync.clj index e19616db5f8635c5ecf56d031ac19436dca2f7dc..372a4e7513fe8e5e6e2d9980762a615c74426c2f 100644 --- a/src/metabase/driver/sync.clj +++ b/src/metabase/driver/sync.clj @@ -89,7 +89,7 @@ (fetch-and-sync-database-active-tables! driver database) ;; Ok, now if we had a _metabase_metadata table from earlier we can go ahead and sync from it - (sync-metabase-metadata-table! driver database)) + (sync-metabase-metadata-table! driver database active-tables)) (defn- -sync-database-with-tracking! [driver database] (let [start-time (System/currentTimeMillis) @@ -125,8 +125,8 @@ `keypath` is of the form `table-name.key` or `table-name.field-name.key`, where `key` is the name of some property of `Table` or `Field`. This functionality is currently only used by the Sample Dataset. In order to use this functionality, drivers must implement optional fn `:table-rows-seq`." - [driver database] - (doseq [{table-name :name} (driver/active-tables driver database)] + [driver database active-tables] + (doseq [{table-name :name} active-tables] (when (= (s/lower-case table-name) "_metabase_metadata") (doseq [{:keys [keypath value]} (driver/table-rows-seq driver database table-name)] (let [[_ table-name field-name k] (re-matches #"^([^.]+)\.(?:([^.]+)\.)?([^.]+)$" keypath)]