Я использую Kotlin Exposed для определения таблицы следующим образом:
object Headers : Table("headers") {
val id = uuid("id").primaryKey()
// tons more columns
}
И у меня есть еще одна таблица, определенная следующим образом
object Transactions : Table("transactions") {
val headerId = (uuid("header_id").references(Headers.id)).index("custom_header_index")
// tons more columns
}
Теперь, как вы видите, я пытаюсьсоздать индекс для этой ссылки / FOREIGN KEY, потому что, если я попытаюсь запросить это отношение, я получу следующий результат
EXPLAIN SELECT * FROM transactions WHERE header_id = 'bdbfc5d6-9cf1-430a-a361-a5f96cc7d799'
Gather (cost=1000.00..13771.31 rows=8 width=171)"
Workers Planned: 2"
-> Parallel Seq Scan on transactions (cost=0.00..12770.51 rows=3 width=171)"
Filter: (header_id = 'bdbfc5d6-9cf1-430a-a361-a5f96cc7d799'::uuid)"
Это выполняется последовательное сканирование.И поскольку эта таблица будет содержать сотни тысяч записей, это невыносимо медленно.
Я попробовал несколько вещей, чтобы заставить его работать, но никакие синтаксические изменения, кажется, не вызывают каких-либо изменений схемы
примеры:
// no infix
val headerId = (uuid("header_id").references(Headers.id)).index("custom_header_index")
// infix
val headerId = (uuid("header_id") references Headers.id).index("custom_header_index")
// index before reference
val headerId = (uuid("header_id").index("custom_header_index") references Headers.id)
Я пробовал все это с именами индексов и без них.
Я также должен отметить, что я использую
SchemaUtils.createMissingTablesAndColumns(Headers, Transactions)
, который в любом другом типе столбца обнаруживает изменение индекса, но не в отношении внешних связей.
Что я делаю не так и как я могу получить доступ к kotlin для создания этих индексов?
РЕДАКТИРОВАТЬ: УТОЧНЕНИЕ
Извините, мой вопрос не указал, что моя проблема в том, что Kotlin Exposed не создает эти индексы.Когда я создаю их вручную, все работает должным образом.
Тем временем я также нашел вероятную причину этой проблемы
for (table in tables) {
val existingTableIndices = currentDialect.existingIndices(table)[table].orEmpty().filterFKeys()
val mappedIndices = table.indices.filterFKeys() // Here foreign keys are filtered
existingTableIndices.forEach { index ->
mappedIndices.firstOrNull { it.onlyNameDiffer(index) }?.let {
exposedLogger.trace("Index on table '${table.tableName}' differs only in name: in db ${index.indexName} -> in mapping ${it.indexName}")
nameDiffers.add(index)
nameDiffers.add(it)
}
}
notMappedIndices.getOrPut(table.nameInDatabaseCase(), {hashSetOf()}).addAll(existingTableIndices.subtract(mappedIndices))
missingIndices.addAll(mappedIndices.subtract(existingTableIndices))
}
Приведенный выше код взят из библиотеки Exposed и фильтроввсе индексы, которые он должен создать, и удаляет их, если в столбце есть внешний ключ, что делает невозможным создание регулярных индексов для этих столбцов.
Вероятно, я создам проблему в их репозитории github и обновлюэтот вопрос, если он когда-нибудь будет исправлен.