Postgresql to_char значительно замедляет запрос a

#sql #postgresql

#sql #postgresql

Вопрос:

Я пытаюсь отформатировать столбец с меткой времени с часовым поясом, используя to_char, поскольку я не хочу включать в столбец часть зоны, но разница между запросом, выполняющимся to_char, и без него составляет около 10 секунд, что является большим временем, у меня нет большого опыта работы с базами данных и может быть, я делаю что-то не так.

время запроса без to_char: 1313 мс:

 select distinct on ("Results"."Timestamp") "Results"."Timestamp", 
"TotalParticlesAccum", "BioAccumulated", "FlowVolume", 
"DCOffsetCh0", "DCOffsetCh1", "DCOffsetCh2", 
"LaserPower", "LaserCurrent", "LaserTemperature", 
"LaserRunHour", "FlowRate", "FlowPressure", 
"FlowTemperature", "CpuTemperature", "PwbTemperature", 
"Temperature1", "Temperature2", "Temperature3", 
"Temperature4", "TotalParticles", "Bio" 
from "Results"
Left join "SensorLog" On "Results"."SampleID" = "SensorLog"."SampleID"
where "Results"."SampleID" = id order by 1 asc;
 

время запроса с to_char: 12354 мс

 select distinct on (to_char("Results"."Timestamp",'YYYY/MM/DD HH24:MI:SS'))     
to_char("Results"."Timestamp",'YYYY/MM/DD HH24:MI:SS'), 
"TotalParticlesAccum", "BioAccumulated", "FlowVolume", 
"DCOffsetCh0", "DCOffsetCh1", "DCOffsetCh2", 
"LaserPower", "LaserCurrent", "LaserTemperature", 
"LaserRunHour", "FlowRate", "FlowPressure", 
"FlowTemperature", "CpuTemperature", "PwbTemperature", 
"Temperature1", "Temperature2", "Temperature3", 
"Temperature4", "TotalParticles", "Bio" 
from "Results"
Left join "SensorLog" On "Results"."SampleID" = "SensorLog"."SampleID"
where "Results"."SampleID" = id order by 1 asc;
 

Я думаю, я знаю, что проблема в том, что мне нужно to_char дважды, но если у меня этого нет, это выдает ошибку
ОШИБКА: SELECT DISTINCT В выражениях должен соответствовать первоначальному порядку ПО выражениям

Комментарии:

1. Покажите нам выходные explain analyze данные для обоих запросов (например, загруженные в explain.depesz.com ) и определение таблиц, включая все их индексы

2. причина, по которой я использую to_char, заключается в том, что столбец имеет часовой пояс, я не хочу, чтобы часовой пояс включался в результат

3. Я предполагаю, что to_char не позволяет postgres использовать индекс, который в противном случае использовался бы. Если вы опубликуете поясняющую информацию, мы узнаем больше.

4. from "Results","SensorLog where "Results"."SampleID" = 839 для меня это похоже на картезианский продукт

Ответ №1:

Просто оберните быстрый запрос одним с нужным форматом

 select
    to_char("Timestamp",'YYYY/MM/DD HH24:MI:SS') as "Timestamp",
    "TotalParticlesAccum", "BioAccumulated", "FlowVolume", 
    "DCOffsetCh0", "DCOffsetCh1", "DCOffsetCh2", 
    "LaserPower", "LaserCurrent", "LaserTemperature", 
    "LaserRunHour", "FlowRate", "FlowPressure", 
    "FlowTemperature", "CpuTemperature", "PwbTemperature", 
    "Temperature1", "Temperature2", "Temperature3", 
    "Temperature4", "TotalParticles", "Bio"     
from (
    select distinct on ("Results"."Timestamp")
        "Results"."Timestamp", 
        "TotalParticlesAccum", "BioAccumulated", "FlowVolume", 
        "DCOffsetCh0", "DCOffsetCh1", "DCOffsetCh2", 
        "LaserPower", "LaserCurrent", "LaserTemperature", 
        "LaserRunHour", "FlowRate", "FlowPressure", 
        "FlowTemperature", "CpuTemperature", "PwbTemperature", 
        "Temperature1", "Temperature2", "Temperature3", 
        "Temperature4", "TotalParticles", "Bio" 
    from
        "Results"
        Left join
        "SensorLog" On "Results"."SampleID" = "SensorLog"."SampleID"
    where "Results"."SampleID" = id
    order by 1 asc
) s
 

Комментарии:

1. это звучит как хорошая идея, но я получаю сообщение об ошибке: отсутствует запись в предложении для таблицы «Результаты» СТРОКА 1: выберите to_char(«Результаты». » Временная метка»,’ГГГГ / ММ / ДД ЧЧ24: MI: SS’…

2. @Ubaldo Я не вижу этого в коде, который я опубликовал. Вы можете просто скопировать и вставить?

3. Извините, мой плохой, это сработало отлично, спасибо!, именно то, что я искал

Ответ №2:

мое предложение заключается в использовании необработанного поля для группировки и упорядочивания, но отформатируйте его так, как вы хотите, в предложении select:

 SELECT DISTINCT ON ("Timestamp")
    to_char("Results"."Timestamp", 'YYYY/MM/DD HH24:MI:SS')
    ,"TotalParticlesAccum"
    ,"BioAccumulated"
    ,"FlowVolume"
    ,"DCOffsetCh0"
    ,"DCOffsetCh1"
    ,"DCOffsetCh2"
    ,"LaserPower"
    ,"LaserCurrent"
    ,"LaserTemperature"
    ,"LaserRunHour"
    ,"FlowRate"
    ,"FlowPressure"
    ,"FlowTemperature"
    ,"CpuTemperature"
    ,"PwbTemperature"
    ,"Temperature1"
    ,"Temperature2"
    ,"Temperature3"
    ,"Temperature4"
    ,"TotalParticles"
    ,"Bio"
FROM "Results"
Left join "SensorLog" On "Results"."SampleID" = "SensorLog"."SampleID"
WHERE "Results"."SampleID" = 839
ORDER BY "Timestamp" ASC
 

Без sqlfiddle я не уверен на 100%, что это сработает, но, скорее всего, это правильный путь.

Комментарии:

1. @Andreas в исходном вопросе OP было картезианское произведение, которое теперь заменено на ЛЕВОЕ СОЕДИНЕНИЕ.

Ответ №3:

Временная метка — это зарезервированное слово; вы не можете назвать временную метку столбца без проблем. Попробуйте изменить его.