diff options
author | Nick Marino <[email protected]> | 2013-04-12 13:57:58 -0400 |
---|---|---|
committer | Nick Marino <[email protected]> | 2013-04-12 15:17:01 -0400 |
commit | ac9540ee6d508f707abf40dd79ebd738f4272db7 (patch) | |
tree | 35df5d2a4568823985f4474996d6ce9866113ad1 | |
parent | e09920ed1da9ebf3efa814d8f5039140109beab3 (diff) | |
download | otp-ac9540ee6d508f707abf40dd79ebd738f4272db7.tar.gz otp-ac9540ee6d508f707abf40dd79ebd738f4272db7.tar.bz2 otp-ac9540ee6d508f707abf40dd79ebd738f4272db7.zip |
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.)
-rw-r--r-- | lib/mnesia/src/mnesia_index.erl | 9 |
1 files changed, 7 insertions, 2 deletions
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. |