From ac9540ee6d508f707abf40dd79ebd738f4272db7 Mon Sep 17 00:00:00 2001 From: Nick Marino Date: Fri, 12 Apr 2013 13:57:58 -0400 Subject: Optimize index creation for Mnesia set tables ETS bag tables have very poor performance on insertion if you have lots of rows with duplicate keys, since it has to check each existing record and make sure it's not inserting any duplicates. This can lead to some pretty drastic slowdowns when inserting lots of rows into an Mnesia table, IF you're introducing lots of duplicate values into an indexed column. As it turns out, we can fix this by switching to duplicate_bag tables for storing Mnesia indexes on tables of type 'set', and it ultimately makes no functional difference since we will never actually attempt to insert any duplicate records anyway. (We would have to make some bigger changes to make this work for Mnesia bag tables though, so that is left as a possible enhancement for the future.) --- lib/mnesia/src/mnesia_index.erl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/mnesia/src/mnesia_index.erl b/lib/mnesia/src/mnesia_index.erl index f9f3ce2ea4..11e729f565 100644 --- a/lib/mnesia/src/mnesia_index.erl +++ b/lib/mnesia/src/mnesia_index.erl @@ -301,7 +301,12 @@ make_ram_index(Tab, [Pos | Tail]) -> add_ram_index(Tab, Pos) when is_integer(Pos) -> verbose("Creating index for ~w ~n", [Tab]), - Index = mnesia_monitor:mktab(mnesia_index, [bag, public]), + SetOrBag = val({Tab, setorbag}), + IndexType = case SetOrBag of + set -> duplicate_bag; + bag -> bag + end, + Index = mnesia_monitor:mktab(mnesia_index, [IndexType, public]), Insert = fun(Rec, _Acc) -> true = ?ets_insert(Index, {element(Pos, Rec), element(2, Rec)}) end, @@ -309,7 +314,7 @@ add_ram_index(Tab, Pos) when is_integer(Pos) -> true = ets:foldl(Insert, true, Tab), mnesia_lib:db_fixtable(ram_copies, Tab, false), mnesia_lib:set({Tab, {index, Pos}}, Index), - add_index_info(Tab, val({Tab, setorbag}), {Pos, {ram, Index}}); + add_index_info(Tab, SetOrBag, {Pos, {ram, Index}}); add_ram_index(_Tab, snmp) -> ok. -- cgit v1.2.3