diff --git a/Control/StoreGate/StoreGate/VarHandleKey.h b/Control/StoreGate/StoreGate/VarHandleKey.h
index eaae6c24807a7f6b40f4c22a662d1e4732cbc541..bfa6e0320aeed2835c30080dfcbc477675ecdfd6 100644
--- a/Control/StoreGate/StoreGate/VarHandleKey.h
+++ b/Control/StoreGate/StoreGate/VarHandleKey.h
@@ -189,6 +189,13 @@ public:
   virtual StatusCode start();
 
 
+  /** 
+   * @brief Return the hashed StoreGate key.
+   *
+   * May be 0 if not yet initialized.
+   */
+  SG::sgkey_t hashedKey() const;
+
 private:
   /// Set the owning handle.  Only callable from VarHandleBase.
   friend class VarHandleBase;
@@ -228,6 +235,9 @@ private:
   /// StoreGate key, that doesn't include the storename
   std::string m_sgKey;
 
+  /// The hashed StoreGate key.  May be 0 if not yet initialized.
+  SG::sgkey_t m_hashedKey = 0;
+
   /// Cache test for whether we're referencing the event store.
   bool m_isEventStore = false;
 
diff --git a/Control/StoreGate/StoreGate/VarHandleKey.icc b/Control/StoreGate/StoreGate/VarHandleKey.icc
index 39415cc71ede3f83fcc9f8146b26114d967a61ca..c130972b2b3f5a4778fee14c6693ce918d4a4db3 100644
--- a/Control/StoreGate/StoreGate/VarHandleKey.icc
+++ b/Control/StoreGate/StoreGate/VarHandleKey.icc
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 // $Id$
 /**
@@ -72,5 +72,16 @@ StatusCode VarHandleKey::start()
   return StatusCode::SUCCESS;
 }
 
+/** 
+ * @brief Return the hashed StoreGate key.
+ *
+ * May be 0 if not yet initialized.
+ */
+inline
+SG::sgkey_t VarHandleKey::hashedKey() const
+{
+  return m_hashedKey;
+}
+
 
 } // namespace SG
diff --git a/Control/StoreGate/share/VarHandleBase_test.txt b/Control/StoreGate/share/VarHandleBase_test.txt
index ec103ddc669252cfc6e863edd30e1925f9bf4cf3..78e73d95195a425f6c729e2b07e5b4b66915bd62 100644
--- a/Control/StoreGate/share/VarHandleBase_test.txt
+++ b/Control/StoreGate/share/VarHandleBase_test.txt
@@ -1,2 +1,3 @@
+ApplicationMgr.ExtSvc={"StoreGateSvc/StoreGateSvc"};
 ApplicationMgr.ExtSvc={"StoreGateSvc/OtherStore"};
 OtherStore.ProxyProviderSvc="";
diff --git a/Control/StoreGate/src/VarHandleBase.cxx b/Control/StoreGate/src/VarHandleBase.cxx
index a1d8acb6dff6d15d6cc56efd3e265c10095ea29c..51c38db1654606ce705889efc11abeb17214265c 100644
--- a/Control/StoreGate/src/VarHandleBase.cxx
+++ b/Control/StoreGate/src/VarHandleBase.cxx
@@ -504,7 +504,11 @@ namespace SG {
       if (store) m_store = store;
     }
 
-    StatusCode sc = this->setState(m_store->proxy(this->clid(), this->key()));
+    SG::DataProxy* proxy = m_store->proxy_exact (m_key->hashedKey());
+    if (!proxy) {
+      proxy = m_store->proxy(this->clid(), this->key());
+    }
+    StatusCode sc = this->setState(proxy);
 
     // Failure to find the proxy is ok in the case of a @c WriteHandle
     // that has not yet been written to.
diff --git a/Control/StoreGate/src/VarHandleKey.cxx b/Control/StoreGate/src/VarHandleKey.cxx
index 9eeae80388a5e30c66e6e13cc3e990107f0f5c54..0b798cd38893091a48296217b466171e2f21c7bd 100644
--- a/Control/StoreGate/src/VarHandleKey.cxx
+++ b/Control/StoreGate/src/VarHandleKey.cxx
@@ -112,6 +112,7 @@ StatusCode VarHandleKey::initialize (bool used /*= true*/)
   if (!used) {
     Gaudi::DataHandle::updateKey ( "" );
     m_sgKey = "";
+    m_hashedKey = 0;
     return StatusCode::SUCCESS;
   }
 
@@ -130,6 +131,8 @@ StatusCode VarHandleKey::initialize (bool used /*= true*/)
     return StatusCode::FAILURE;
   }
 
+  m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
+
   return StatusCode::SUCCESS;
 }
 
@@ -216,6 +219,8 @@ void VarHandleKey::updateKey(const std::string& /*key*/) const
 void VarHandleKey::parseKey (const std::string& key,
                              const std::string& storeName)
 {
+  m_hashedKey = 0;
+
   std::string sn;
   // test if storeName has classname
   std::string::size_type sp = storeName.find("/");
@@ -296,6 +301,7 @@ void VarHandleKey::updateHandle (const std::string& name)
   // Don't invalidate a stored pointer if the handle is already pointing
   // at the desired service.
   if (m_storeHandle.name() != name) {
+    m_hashedKey = 0;
     m_storeHandle = ServiceHandle<IProxyDict>(name, "VarHandleKey");
     m_isEventStore =  (name == StoreID::storeName(StoreID::EVENT_STORE) ||
                        name == StoreID::storeName(StoreID::PILEUP_STORE));
diff --git a/Control/StoreGate/test/ReadHandle_test.cxx b/Control/StoreGate/test/ReadHandle_test.cxx
index a84d21e4b107ea3523a76a176c413319a5219534..2315d1ebdf35608dc966420940ce1c158216ad74 100644
--- a/Control/StoreGate/test/ReadHandle_test.cxx
+++ b/Control/StoreGate/test/ReadHandle_test.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id$
@@ -14,6 +14,7 @@
 #undef NDEBUG
 #include "AthenaKernel/ExtendedEventContext.h"
 #include "StoreGate/ReadHandle.h"
+#include "StoreGate/StoreGateSvc.h"
 #include "StoreGate/exceptions.h"
 #include "SGTools/TestStore.h"
 #include "AthenaKernel/CLASS_DEF.h"
@@ -21,6 +22,7 @@
 #include "TestTools/expect_exception.h"
 #include "AthenaKernel/errorcheck.h"
 #include "CxxUtils/unused.h"
+#include "boost/timer/timer.hpp"
 #include <cassert>
 #include <iostream>
 
@@ -335,7 +337,40 @@ void test6()
 }
 
 
-int main()
+//************************************************************************
+
+
+unsigned int perftest (ISvcLocator* svcloc, unsigned int ntry)
+{
+  StoreGateSvc* sg = nullptr;
+  assert (svcloc->service ("StoreGateSvc", sg).isSuccess());
+  assert (sg->record (std::make_unique<MyObj> (42), "MyObj", false).isSuccess());
+
+  SG::ReadHandleKey<MyObj> key ("MyObj");
+  assert (key.initialize().isSuccess());
+
+  EventContext ctx;
+  ctx.setExtension( Atlas::ExtendedEventContext(sg->hiveProxyDict()) );
+  unsigned int sum = 0;
+  boost::timer::cpu_timer timer;
+  for (unsigned int i=0; i < ntry; i++) {
+    SG::ReadHandle<MyObj> h (key, ctx);
+    sum += h->x;
+  }
+  timer.stop();
+  boost::timer::cpu_times times = timer.elapsed();
+  std::cout << ntry << " times: " << boost::timer::format(times);
+  std::cout << "Each: " << (float)times.user / ntry / 1000 << " us (user)\n";
+
+  return sum;
+}
+
+
+
+//************************************************************************
+
+
+int main (int argc, char** argv)
 {
   errorcheck::ReportMessage::hideErrorLocus();
   ISvcLocator* svcloc;
@@ -344,6 +379,17 @@ int main()
     return 1;
   }
 
+  if (argc >= 2 && strncmp (argv[1], "--perf", 6) == 0) {
+    unsigned int ntry = 1000000;
+    const char* p = strchr (argv[1], '=');
+    if (p) {
+      ntry = atoi (p+1);
+      if (ntry < 1) ntry = 1;
+    }
+    perftest (svcloc, ntry);
+    return 0;
+  }
+
   test1();
   test2();
   test3();
diff --git a/Control/StoreGate/test/VarHandleKey_test.cxx b/Control/StoreGate/test/VarHandleKey_test.cxx
index ecdc129c79b52b3fc2849f5f281d6a68e9ab1135..835c7ac421b70c860147c5afd9fdd1139b89d81b 100644
--- a/Control/StoreGate/test/VarHandleKey_test.cxx
+++ b/Control/StoreGate/test/VarHandleKey_test.cxx
@@ -40,11 +40,13 @@ void test1()
   assert (k1.mode() == Gaudi::DataHandle::Reader);
   assert (k1.storeHandle().name() == "StoreGateSvc");
   assert (!k1.storeHandle().isSet());
+  assert (k1.hashedKey() == 0);
   assert (k1.initialize().isSuccess());
   assert (k1.storeHandle().isSet());
   assert (k1.start().isSuccess());
   assert (!k1.isCondition());
   assert (!k1.empty());
+  assert (k1.hashedKey() == 752331202);
 
   k1 = "aab";
   assert (k1.clid() == 1234);