diff --git a/src/plugins/help/helpindexfilter.cpp b/src/plugins/help/helpindexfilter.cpp
index 5018748468443bdb35f1edc72779ac11e44299bc..aad01d9e63bf5408b88e75a0423a278f5d515bea 100644
--- a/src/plugins/help/helpindexfilter.cpp
+++ b/src/plugins/help/helpindexfilter.cpp
@@ -50,19 +50,36 @@ using namespace Help::Internal;
 
 Q_DECLARE_METATYPE(ILocatorFilter*);
 
+static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, "
+    "d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, "
+    "NamespaceTable f WHERE a.FileId=d.FileId AND d.FolderId=e.Id AND "
+    "a.NamespaceId=f.Id AND a.Name='%1'";
+
 // -- HelpIndexFilter::HelpFileReader
 
 class HelpIndexFilter::HelpFileReader
 {
+    struct dbCleaner {
+        dbCleaner(const QString &dbName)
+            : name(dbName) {}
+        ~dbCleaner() {
+            QSqlDatabase::removeDatabase(name);
+        }
+        QString name;
+    };
+
 public:
     HelpFileReader();
     ~HelpFileReader();
 
 public:
     void updateHelpFiles();
-    QList<FilterEntry> matchesFor(const QString &entry, ILocatorFilter *locator);
+    QMap<QString, QUrl> linksForKey(const QString &key);
+    QList<FilterEntry> matchesFor(const QString &entry, ILocatorFilter *locator,
+        int maxHits = INT_MAX);
 
 private:
+    QIcon m_icon;
     bool m_initialized;
     QStringList m_helpFiles;
 };
@@ -70,6 +87,7 @@ private:
 HelpIndexFilter::HelpFileReader::HelpFileReader()
     : m_initialized(false)
 {
+    m_icon = QIcon(QLatin1String(":/help/images/bookmark.png"));
 }
 
 HelpIndexFilter::HelpFileReader::~HelpFileReader()
@@ -96,8 +114,55 @@ void HelpIndexFilter::HelpFileReader::updateHelpFiles()
     QSqlDatabase::removeDatabase(id);
 }
 
+QUrl buildQUrl(const QString &nameSpace, const QString &folder,
+    const QString &relFileName, const QString &anchor)
+{
+    QUrl url;
+    url.setScheme(QLatin1String("qthelp"));
+    url.setAuthority(nameSpace);
+    url.setPath(folder + QLatin1Char('/') + relFileName);
+    url.setFragment(anchor);
+    return url;
+}
+
+QMap<QString, QUrl>HelpIndexFilter::HelpFileReader::linksForKey(const QString &key)
+{
+    if (!m_initialized) {
+        updateHelpFiles();
+        m_initialized = true;
+    }
+
+    QMap<QString, QUrl> links;
+    const QLatin1String sqlite("QSQLITE");
+    const QLatin1String name("HelpIndexFilter::HelpFileReader::linksForKey");
+
+    dbCleaner cleaner(name);
+    QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
+    if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
+        foreach(const QString &file, m_helpFiles) {
+            if (!QFile::exists(file))
+                continue;
+            db.setDatabaseName(file);
+            if (db.open()) {
+                QSqlQuery query = QSqlQuery(db);
+                query.setForwardOnly(true);
+                query.exec(QString::fromLatin1(linksForKeyQuery).arg(key));
+                while (query.next()) {
+                    QString title = query.value(0).toString();
+                    if (title.isEmpty()) // generate a title + corresponding path
+                        title = key + QLatin1String(" : ") + query.value(3).toString();
+                    links.insertMulti(title, buildQUrl(query.value(1).toString(),
+                        query.value(2).toString(), query.value(3).toString(),
+                        query.value(4).toString()));
+                }
+            }
+        }
+    }
+    return links;
+}
+
 QList<FilterEntry> HelpIndexFilter::HelpFileReader::matchesFor(const QString &id,
-    ILocatorFilter *locator)
+    ILocatorFilter *locator, int maxHits)
 {
     if (!m_initialized) {
         updateHelpFiles();
@@ -107,31 +172,30 @@ QList<FilterEntry> HelpIndexFilter::HelpFileReader::matchesFor(const QString &id
     QList<FilterEntry> entries;
     const QLatin1String sqlite("QSQLITE");
     const QLatin1String name("HelpIndexFilter::HelpFileReader::matchesFor");
-    foreach(const QString &file, m_helpFiles) {
-        if (!QFile::exists(file))
-            continue;
-        {
-            QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
-            if (db.driver()
-                && db.driver()->lastError().type() == QSqlError::NoError) {
-                db.setDatabaseName(file);
-                if (db.open()) {
-                    QSqlQuery query = QSqlQuery(db);
-                    query.setForwardOnly(true);
-                    query.exec(QString::fromLatin1("SELECT DISTINCT Name FROM "
-                        "IndexTable WHERE Name LIKE '%%1%'").arg(id));
-                    while (query.next()) {
-                        const QString &key = query.value(0).toString();
-                        if (!key.isEmpty()) {
-                            // NOTE: do not use an icon since it is really slow
-                            entries.append(FilterEntry(locator, key, QVariant(),
-                                QIcon()));
-                        }
+
+    dbCleaner cleaner(name);
+    QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
+    if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
+        foreach(const QString &file, m_helpFiles) {
+            if (!QFile::exists(file))
+                continue;
+            db.setDatabaseName(file);
+            if (db.open()) {
+                QSqlQuery query = QSqlQuery(db);
+                query.setForwardOnly(true);
+                query.exec(QString::fromLatin1("SELECT DISTINCT Name FROM "
+                    "IndexTable WHERE Name LIKE '%%1%'").arg(id));
+                while (query.next()) {
+                    const QString &key = query.value(0).toString();
+                    if (!key.isEmpty()) {
+                        entries.append(FilterEntry(locator, key, QVariant(),
+                            m_icon));
+                        if (entries.count() == maxHits)
+                            return entries;
                     }
                 }
             }
         }
-        QSqlDatabase::removeDatabase(name);
     }
     return entries;
 }
@@ -176,18 +240,18 @@ ILocatorFilter::Priority HelpIndexFilter::priority() const
 QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
 {
     if (entry.length() < 2)
-        return QList<FilterEntry>();
+        return m_fileReader->matchesFor(entry, this, 300);
     return m_fileReader->matchesFor(entry, this);
 }
 
 void HelpIndexFilter::accept(FilterEntry selection) const
 {
-    const QHelpEngineCore &engine = HelpManager::helpEngineCore();
-    QMap<QString, QUrl> links = engine.linksForIdentifier(selection.displayName);
+    const QString &key = selection.displayName;
+    const QMap<QString, QUrl> &links = m_fileReader->linksForKey(key);
     if (links.size() == 1) {
         emit linkActivated(links.begin().value());
     } else if (!links.isEmpty()) {
-        emit linksActivated(links, selection.displayName);
+        emit linksActivated(links, key);
     }
 }