Building master @ 41a8d2b96ff5cbc2efa9b0996f30228d0a625fdb (sqlite):
```bash
./autogen.sh
./configure --without-bdb --without-gui --with-sqlite
  with wallet     = yes
    with sqlite   = yes
    with bdb      = no
gmake -j8
src/test/test_bitcoin --run_test=wallet_tests --log_level=all
...
wallet/test/wallet_tests.cpp:696: Entering test case "CreateWallet"
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:734: info: check m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error) has passed
wallet/test/wallet_tests.cpp:740: info: check rescan_completed has passed
wallet/test/wallet_tests.cpp:741: info: check addtx_count == 2 has passed
wallet/test/wallet_tests.cpp:744: info: check wallet->mapWallet.count(block_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:745: info: check wallet->mapWallet.count(mempool_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:753: info: check addtx_count == 4 has passed
wallet/test/wallet_tests.cpp:767: info: check rescan_completed has passed
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:772: info: check m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error) has passed
wallet/test/wallet_tests.cpp:780: info: check addtx_count == 4 has passed
wallet/test/wallet_tests.cpp:783: info: check wallet->mapWallet.count(block_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:784: info: check wallet->mapWallet.count(mempool_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:696: Leaving test case "CreateWallet"; testing time: 201296644us
wallet/test/wallet_tests.cpp:791: Entering test case "ZapSelectTx"
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:810: info: check wallet->HasWalletSpend(prev_hash) has passed
wallet/test/wallet_tests.cpp:811: info: check wallet->mapWallet.count(block_hash) == 1u has passed
wallet/test/wallet_tests.cpp:814: info: check wallet->ZapSelectTx(vHashIn, vHashOut) == DBErrors::LOAD_OK has passed
wallet/test/wallet_tests.cpp:816: info: check !wallet->HasWalletSpend(prev_hash) has passed
wallet/test/wallet_tests.cpp:817: info: check wallet->mapWallet.count(block_hash) == 0u has passed
wallet/test/wallet_tests.cpp:791: Leaving test case "ZapSelectTx"; testing time: 200866629us
```

Compare that to running the same tests after building with just bdb:
```bash
gmake clean
./configure --without-gui --with-sqlite=no
  with wallet     = yes
    with sqlite   = no
    with bdb      = yes
gmake -j8
src/test/test_bitcoin --run_test=wallet_tests --log_level=all
...
wallet/test/wallet_tests.cpp:696: Entering test case "CreateWallet"
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:734: info: check m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error) has passed
wallet/test/wallet_tests.cpp:740: info: check rescan_completed has passed
wallet/test/wallet_tests.cpp:741: info: check addtx_count == 2 has passed
wallet/test/wallet_tests.cpp:744: info: check wallet->mapWallet.count(block_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:745: info: check wallet->mapWallet.count(mempool_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:753: info: check addtx_count == 4 has passed
wallet/test/wallet_tests.cpp:767: info: check rescan_completed has passed
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:772: info: check m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error) has passed
wallet/test/wallet_tests.cpp:780: info: check addtx_count == 4 has passed
wallet/test/wallet_tests.cpp:783: info: check wallet->mapWallet.count(block_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:784: info: check wallet->mapWallet.count(mempool_tx.GetHash()) == 1U has passed
wallet/test/wallet_tests.cpp:696: Leaving test case "CreateWallet"; testing time: 2139054us
wallet/test/wallet_tests.cpp:791: Entering test case "ZapSelectTx"
wallet/test/wallet_tests.cpp:69: info: check SignTransaction(mtx, &keystore, coins, SIGHASH_ALL, input_errors) has passed
wallet/test/wallet_tests.cpp:810: info: check wallet->HasWalletSpend(prev_hash) has passed
wallet/test/wallet_tests.cpp:811: info: check wallet->mapWallet.count(block_hash) == 1u has passed
wallet/test/wallet_tests.cpp:814: info: check wallet->ZapSelectTx(vHashIn, vHashOut) == DBErrors::LOAD_OK has passed
wallet/test/wallet_tests.cpp:816: info: check !wallet->HasWalletSpend(prev_hash) has passed
wallet/test/wallet_tests.cpp:817: info: check wallet->mapWallet.count(block_hash) == 0u has passed
wallet/test/wallet_tests.cpp:791: Leaving test case "ZapSelectTx"; testing time: 1821042us
```

In the sqlite case,`CreateWallet` is taking ~100x longer: `201296644us` vs `2139054us`. `ZapWalletTx` is similar: `200866629us` vs `1821042us`. [Full logs here](https://gist.github.com/fanquake/09e983acf0792482534f0fe7e916a03a).

I thought this might be some weird macOS behaviour, but I tested on Linux, and am also seeing up to 27x difference. `CreateWallet`: `27905993us` vs `1092394us`. `ZapWalletTx`: `28024310us` vs `969432us`. [Full logs here](https://gist.github.com/fanquake/a1104888b5574af00a40a9998cfd0b36).
{
public:
    
    bool HasWalletSupport() const override {return true;}
    
    void AddWalletOptions(ArgsManager& argsman) const override;
    
    bool ParameterInteraction() const override;
    
    void Construct(NodeContext& node) const override;
};
const WalletInitInterface& g_wallet_init_interface = WalletInit();
void WalletInit::AddWalletOptions(ArgsManager& argsman) const
{
    argsman.AddArg("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(DEFAULT_ADDRESS_TYPE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-avoidpartialspends", strprintf("Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u (always enabled for wallets with \"avoid_reuse\" enabled))", DEFAULT_AVOIDPARTIALSPENDS), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-disablewallet", "Do not load the wallet and disable wallet RPC calls", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-discardfee=<amt>", strprintf("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
                                                                "Note: An output is discarded if it is dust at this rate, but we will always discard up to the dust relay fee and a discard fee above that is limited by the fee estimate for the longest target",
                                                              CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-fallbackfee=<amt>", strprintf("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data. 0 to entirely disable the fallbackfee feature. (default: %s)",
                                                               CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-keypool=<n>", strprintf("Set key pool size to <n> (default: %u). Warning: Smaller sizes may increase the risk of losing funds when restoring from an old backup, if none of the addresses in the original keypool have been used.", DEFAULT_KEYPOOL_SIZE), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
    argsman.AddArg("-maxapsfee=<n>", strprintf("Spend up to this amount in additional (absolute) fees (in %s) if it allows the use of partial spend avoidance (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_MAX_AVOIDPARTIALSPEND_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);