我注意到表名的长度会影响创建这些表期间的性能。下面是重现该问题的代码示例:
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
int main() {
  int i, sr;
  char table_query[1000];
  sqlite3* db;
  sr = sqlite3_open("test.db", &db);
  assert(sr == SQLITE_OK);
  sr = sqlite3_exec(db, "PRAGMA synchronous=OFF", NULL, NULL, NULL);
  assert(sr == SQLITE_OK);
  sr = sqlite3_exec(db, "PRAGMA journal_mode=OFF", NULL, NULL, NULL);
  assert(sr == SQLITE_OK);
  sr = sqlite3_exec(db, "PRAGMA temp_store=MEMORY", NULL, NULL, NULL);
  assert(sr == SQLITE_OK);
  sr = sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION;", NULL, NULL, NULL);
  assert(sr == SQLITE_OK);
  for (i = 0; i < 10000; ++i) {
  #ifdef LONG_NAMES
   sprintf(table_query, "CREATE TABLE `TABLE_%d_AKLKEKABCDEFGHIJK4C6F766520416C6C20546865205061696E204177617920496E636C204B796175202620416C626572742052656D69782020434452` (content);", i);
  #else
   sprintf(table_query, "CREATE TABLE `TABLE_%d` (content);", i);
  #endif
   sr = sqlite3_exec(db, table_query, NULL, NULL, NULL);
   assert(sr == SQLITE_OK);
  }
  sr = sqlite3_exec(db, "END TRANSACTION;", NULL, NULL, NULL);
  assert(sr == SQLITE_OK);
  sr = sqlite3_close(db);
  assert(sr == SQLITE_OK);
  return 0;
}
编译:
gcc main.c sqlite3.c -O3 -DLONG_NAMES -DNDEBUG
gcc main.c sqlite3.c -O3 -DNDEBUG
在我的机器上,当使用相对较短的表名(如TABLE_{table #})时,创建包含 10,000 个表的数据库大约需要 14 秒。这些表名称从 7 个字符到最多 11 个字符不等。
当使用相对较长的表名(如TABLE_{table #}_{some unique identifying name that adds 120 or so characters})时,创建一个包含 10,000 个表的数据库大约需要 60 秒。
创建具有长表名的数据库花费了 4 倍多的时间!
为什么会这样?这是预期的行为还是错误?
而且由于创建具有长名称的表会对性能产生负面影响,这让我想知道这样的数据库上的查询性能是否也会受到负面影响。这个SO 答案似乎相信关于 MySQL 的答案是“否”,但没有给出参考。
想法?
PS:我正在使用最新的合并版本的 sqlite (3.8)