Bug 739763 - Fix slow redirects query that with certain data distributions may cause long hangs on first page load.

r=dietrich
This commit is contained in:
Marco Bonardo 2012-04-02 22:48:28 +02:00
Родитель b93bb1bc3e
Коммит 24003908e0
3 изменённых файлов: 45 добавлений и 62 удалений

Просмотреть файл

@ -78,40 +78,31 @@ FetchPageInfo(nsRefPtr<Database>& aDB,
NS_PRECONDITION(!NS_IsMainThread(),
"This should not be called on the main thread");
// This query fragment finds the bookmarked uri we want to set the icon for,
// walking up to three redirect levels.
nsCString redirectedBookmarksFragment =
nsPrintfCString(1024,
"SELECT h.url "
"FROM moz_bookmarks b "
"WHERE b.fk = h.id "
// This query finds the bookmarked uri we want to set the icon for,
// walking up to two redirect levels.
nsCString query = nsPrintfCString(768,
"SELECT h.id, h.favicon_id, h.guid, ( "
"SELECT h.url FROM moz_bookmarks b WHERE b.fk = h.id "
"UNION ALL " // Union not directly bookmarked pages.
"SELECT (SELECT url FROM moz_places WHERE id = %s) "
"FROM moz_historyvisits self "
"JOIN moz_bookmarks b ON b.fk = %s "
"LEFT JOIN moz_historyvisits parent ON parent.id = self.from_visit "
"LEFT JOIN moz_historyvisits grandparent ON parent.from_visit = grandparent.id "
"AND parent.visit_type IN (%d, %d) "
"LEFT JOIN moz_historyvisits greatgrandparent ON grandparent.from_visit = greatgrandparent.id "
"AND grandparent.visit_type IN (%d, %d) "
"WHERE self.visit_type IN (%d, %d) "
"AND self.place_id = h.id "
"LIMIT 1 ",
NS_LITERAL_CSTRING("COALESCE(greatgrandparent.place_id, grandparent.place_id, parent.place_id)").get(),
NS_LITERAL_CSTRING("COALESCE(greatgrandparent.place_id, grandparent.place_id, parent.place_id)").get(),
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY,
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY,
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY
);
"SELECT url FROM moz_places WHERE id = ( "
"SELECT COALESCE(grandparent.place_id, parent.place_id) as r_place_id "
"FROM moz_historyvisits dest "
"LEFT JOIN moz_historyvisits parent ON parent.id = dest.from_visit "
"AND dest.visit_type IN (%d, %d) "
"LEFT JOIN moz_historyvisits grandparent ON parent.from_visit = grandparent.id "
"AND parent.visit_type IN (%d, %d) "
"WHERE dest.place_id = h.id "
"AND EXISTS(SELECT 1 FROM moz_bookmarks b WHERE b.fk = r_place_id) "
"LIMIT 1 "
") "
") FROM moz_places h WHERE h.url = :page_url",
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY,
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY
);
nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(NS_LITERAL_CSTRING(
"SELECT h.id, h.favicon_id, h.guid, "
"(") + redirectedBookmarksFragment + NS_LITERAL_CSTRING(") "
"FROM moz_places h WHERE h.url = :page_url"
));
nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(query);
NS_ENSURE_STATE(stmt);
mozStorageStatementScoper scoper(stmt);

Просмотреть файл

@ -576,8 +576,8 @@ interface nsINavBookmarksService : nsISupports
*
* If there is no bookmarked page found, it will return NULL.
*
* @note The function will only return bookmarks in the first 3 levels of
* redirection (1 -> 2 -> 3 -> aURI).
* @note The function will only return bookmarks in the first 2 levels of
* redirection (1 -> 2 -> aURI).
*/
nsIURI getBookmarkedURIFor(in nsIURI aURI);

Просмотреть файл

@ -2195,35 +2195,27 @@ nsNavBookmarks::GetBookmarkedURIFor(nsIURI* aURI, nsIURI** _retval)
// As a bonus the query also checks first if place_id is already a bookmark,
// so you don't have to check that apart.
#define COALESCE_PLACEID \
"COALESCE(greatgrandparent.place_id, grandparent.place_id, parent.place_id) "
nsCString redirectsFragment =
nsPrintfCString(3, "%d,%d",
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY);
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(NS_LITERAL_CSTRING(
"SELECT "
"(SELECT url FROM moz_places WHERE id = :page_id) "
"FROM moz_bookmarks b "
"WHERE b.fk = :page_id "
"UNION ALL " // Not directly bookmarked.
"SELECT "
"(SELECT url FROM moz_places WHERE id = " COALESCE_PLACEID ") "
"FROM moz_historyvisits self "
"JOIN moz_bookmarks b ON b.fk = " COALESCE_PLACEID
"LEFT JOIN moz_historyvisits parent ON parent.id = self.from_visit "
"LEFT JOIN moz_historyvisits grandparent ON parent.from_visit = grandparent.id "
"AND parent.visit_type IN (") + redirectsFragment + NS_LITERAL_CSTRING(") "
"LEFT JOIN moz_historyvisits greatgrandparent ON grandparent.from_visit = greatgrandparent.id "
"AND grandparent.visit_type IN (") + redirectsFragment + NS_LITERAL_CSTRING(") "
"WHERE self.visit_type IN (") + redirectsFragment + NS_LITERAL_CSTRING(") "
"AND self.place_id = :page_id "
"LIMIT 1 " // Stop at the first result.
));
#undef COALESCE_PLACEID
nsCString query = nsPrintfCString(512,
"SELECT url FROM moz_places WHERE id = ( "
"SELECT :page_id FROM moz_bookmarks WHERE fk = :page_id "
"UNION ALL "
"SELECT COALESCE(grandparent.place_id, parent.place_id) AS r_place_id "
"FROM moz_historyvisits dest "
"LEFT JOIN moz_historyvisits parent ON parent.id = dest.from_visit "
"AND dest.visit_type IN (%d, %d) "
"LEFT JOIN moz_historyvisits grandparent ON parent.from_visit = grandparent.id "
"AND parent.visit_type IN (%d, %d) "
"WHERE dest.place_id = :page_id "
"AND EXISTS(SELECT 1 FROM moz_bookmarks WHERE fk = r_place_id) "
"LIMIT 1 "
")",
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY,
nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY
);
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(query);
NS_ENSURE_STATE(stmt);
mozStorageStatementScoper scoper(stmt);