sqlite中的表名长度会影响性能。为什么?

时间:2013-09-03 23:35:05

标签: c performance sqlite database-performance

我注意到表名的长度会影响这些表的创建过程中的性能。这是一个重现问题的代码示例:

#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 answer似乎相信MySQL的答案是“不”,但没有给出引用。

思想?

P.S。:我正在使用最新的合并版本的sqlite(3.8)

2 个答案:

答案 0 :(得分:4)

使用较长的表名称,生成的空数据库文件会大4倍,因为较长的表名称会占用架构中更多的空间。毫不奇怪,SQLite需要花费4倍的时间才能写出4倍的内容。

请注意,表名只存储一次。因此,一旦开始向数据库添加内容,两者之间的相对大小差异将减小,渐近接近1.0。两个数据库之间的绝对大小差异应保持不变。

答案 1 :(得分:2)

较长的表名占用sqlite_master系统表中的更多空间(比较文件大小)。 当SQLite通过该系统表搜索表(或检查新表名是否已存在)时,需要读取和比较更多数据。

但是,在查询时,SQLite仅在第一次实际访问模式时才从系统表中加载数据,因此查询性能不会受到太大影响。