aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia
diff options
context:
space:
mode:
authorNick Marino <[email protected]>2013-04-12 13:57:58 -0400
committerNick Marino <[email protected]>2013-04-12 15:17:01 -0400
commitac9540ee6d508f707abf40dd79ebd738f4272db7 (patch)
tree35df5d2a4568823985f4474996d6ce9866113ad1 /lib/mnesia
parente09920ed1da9ebf3efa814d8f5039140109beab3 (diff)
downloadotp-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.)
Diffstat (limited to 'lib/mnesia')
-rw-r--r--lib/mnesia/src/mnesia_index.erl9
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.