Преди единадесет дни писах в блог за това как Adaptive Dynamic Stats изразходва ресурси в моите производствени RAC бази данни.
След като потуших този пожар, щях да проверя някои лошо представящи се заявки, докладвани от нашите QA хора в тестови и други непроизводствени бази данни. Направих както всеки добър DBA на Oracle. Събрах извикване на съхранена процедура, което дублира проблема. В моята сесия стартирах SQL трасиране и стартирах съхранената процедура. Отне 50 секунди за завършване, докато преди да надстроя от 11.2.0.4 на 12.1.0.2, отнемаха 5 секунди или по-малко. Тази съхранена процедура съдържа редица SQL изрази и SQL трасиране изглеждаше като логично място за начало. Трябваше да знам кой SQL израз в процедурата причинява проблемите.
Пуснах файла за проследяване на SQL през TKPROF и бях изненадан от резултатите. SQL операторите в съхранената процедура изглежда се изпълняваха доста бързо. Но бях посрещнат от много изявления, подобни на следното:
SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) no_parallel */ SUM(C1) FROM (SELECT /*+ qb_name("innerQuery") INDEX_FFS( "XXX" "INDEX_NAME") */ 1 AS C1 FROM "OWNER"."TABLE_NAME" SAMPLE BLOCK(71.048, 8) SEED(1) "XXX") innerQuery
Това е динамично семплиране на работа. Разглеждайки всички оператори за динамично извадка, които се изпълняват в моя файл за проследяване, успях да установя, че те представляват 45 секунди от общото време на изпълнение! Браво!
Динамичното семплиране трябва да ми помогне. Предполага се, че времето, прекарано за получаване на някои примерни статистически данни, е много по-малко от времето, спестено чрез изпълнение на SQL оператор с по-добри статистически данни. Ако не стане, производителността на вашия SQL израз може да пострада, какъвто беше моят случай.
Отбелязах, че едно нещо, което смятах за интересно, е, че тези заявки за динамично вземане на проби се изпълняват веднъж за всяка таблица и веднъж за всеки от нейните индекси. Една от таблиците, включени в моята заявка, има 7 индекса, така че за тази една таблица имах 8 заявки за динамично вземане на проби!
В моя публикация в блога преди 11 дни бях задал параметъра optimizer_dynamic_sampling на 0, което спира изпълнението на тези заявки. Все още не бях поставил тази промяна в нашата тестова среда, така че трябваше да го направя. Веднага след като го направих, производителността на заявката се върна към нормалното. Стойността по подразбиране на този параметър за моята база данни е 2. Вашата стойност по подразбиране може да се различава в зависимост от стойността на настройката optimizer_features_enable. Според тази публикация в блога, стойност 2 означава, че динамичното вземане на проби ще започне, когато поне една от таблиците няма статистически данни. Но за да бъда честен, динамичното вземане на проби не ми носи никакви ползи и ми причинява само вреда. Така че засега ще го оставя изцяло.