Почему коррелированный подзапрос в этом случае намного быстрее, чем функция max ()? - PullRequest
0 голосов
/ 29 апреля 2019

У меня есть база данных SQLite с таблицей акций (около 27000 строк) и таблицей цен на акции (около 60 млн. Строк). Мне нужно получить для каждой акции дату самой последней цены акции. Изначально я использовал

SELECT stockID, MAX(PriceDate) AS MaxDate FROM StockPrices 
GROUP BY stockID

План запроса объяснения дает это:

"0" "0" "0" "SCAN TABLE StockPrices USING COVERING INDEX sqlite_autoindex_StockPrices_1"

Однако для запуска требуется около 21 секунды. Тогда я попробовал это:

SELECT stockID, (SELECT PriceDate FROM StockPrices AS sp
                 WHERE s.stockID= sp.stockID
                 ORDER BY PriceDate DESC
                 ) AS MaxDate FROM Stocks AS s

План запроса объяснения дает это:

"0" "0" "0" "SCAN TABLE Stocks AS s USING COVERING INDEX Index_Stocks_CompanyID"
"0" "0" "0" "EXECUTE CORRELATED SCALAR SUBQUERY 1"
"1" "0" "0" "SEARCH TABLE StockPrices AS sp USING COVERING INDEX sqlite_autoindex_StockPrices_1 (StockListingID=?)"

Теперь я получаю результаты за 3 миллисекунды.

Это резкое сокращение времени вычислений, и я хотел бы лучше понять, откуда возникает эта разница в производительности. У меня сложилось впечатление, что функция max () - будет довольно эффективной, но, очевидно, в некоторых случаях возможны гораздо более быстрые запросы. Оба запроса используют один и тот же покрывающий индекс, поэтому из плана запроса я не могу сказать, почему один из них намного быстрее.

Это операторы создания, используемые для соответствующих таблиц и индексов:

CREATE TABLE StockPrices (StockID INTEGER NOT NULL,PriceDate NUMERIC NOT NULL,PxClose NUMERIC NOT NULL,Volume INTEGER,Source TEXT,DateAdded NUMERIC DEFAULT (JulianDay(CURRENT_TIMESTAMP)), PRIMARY KEY (StockID, PriceDate, PxClose, Volume))

CREATE TABLE Stocks (StockID INTEGER NOT NULL PRIMARY KEY ON CONFLICT ABORT,CompanyID INTEGER NOT NULL REFERENCES Companies (CompanyID),PrimaryListing INTEGER DEFAULT 0,Delisted INTEGER DEFAULT 0,ExchangeID INTEGER NOT NULL REFERENCES Exchanges (ExchangeID),CountryID INTEGER NOT NULL REFERENCES Countries (CountryID),IBKRSymbol TEXT,ISIN TEXT)
CREATE INDEX Index_StockListings_CompanyID ON StockListings (CompanyID)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...