Оптимизация запроса агрегации на основе викиданных - PullRequest
1 голос
/ 03 мая 2019

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

Несколько групп / подзапросов в запросе предназначены для сохранения отношения n-1 от фильма к критериям группировки (год и жанр) и 1-1 связь между фильмом и его продолжительностью.Причиной этого является приблизительно правильная агрегация (отношения n-1 знакомы для специалистов по OLAP и хранилищам данных).

Дополнительные пояснения включены в запрос.Поэтому я не могу опустить группировку, выполненную в подзапросах, а также операторы if или объединение групп.Этот запрос прерывается на конечной точке Wikidata SPARQL .

ВОПРОС

Мне нужно несколько предложений по повышению производительности ... Любые советы по оптимизации ?В случае, если это невозможно, любой, кто знает о каком-либо аутентифицированном способе (чтобы они знали, что я не играю), может запросить Wikidata, чтобы увеличить время ожидания или способ увеличение времени ожидания обычно ?

    # Average duration of films, grouped by their genre and the year of publication       
SELECT  
        ?genre1                    # film genre
        ?year1                     # film year of publication
        (AVG(?duration1) AS ?avg)   # film average duration

WHERE
        {      
            # Calculating the average duration for each single film.
            # As there are films with multiple duration, these durations are 
            # averagred by grouping aggregating durations by film.
            # Hence, a single duration for each film is projected out from the subquery.
            {
              select ?film (avg(?duration) as ?duration1)  
              where{
                ?film   <http://www.wikidata.org/prop/direct/P2047>   ?duration .    
              }group by ?film
            }

            # Here the grouping criteria (genre and year) are calculated.
            # The criteria is grouped by film, so that in case multiple 
            # genre/multiple year exist for a single film, all of them are
            # group concated into a single value.
            # Also in case of a lack of a value of year or genre for some
            # specific film, a dummy value "OtherYear"/"OtherGenre" is generated.
            {
              select ?film (
                                IF
                                (
                                    group_concat(distinct ?year ; separator="-- ") != "", 
                                    # In case multiple year exist for a single film, all of them are group concated into a single value.
                                    group_concat(distinct ?year ; separator="-- "), 
                                   # In case of a lack of a value of year for some specific film, a dummy value "OtherYear" is generated.
                                    "OtherYear"                                        
                                )
                                as ?year1
                              )
                                (
                                IF
                                (
                                    group_concat(distinct ?genre ; separator="-- ") != "",
                                    # In case multiple genre exist for a single film, all of them are group concated into a single value.
                                    group_concat(distinct ?genre ; separator="-- "), 
                                    # In case of a lack of a value of genre for some specific film, a dummy value "OtherGenre" is generated.
                                    "OtherGenre"  
                                )
                                as ?genre1
                              ) 

              where 
              {
                ?film  <http://www.wikidata.org/prop/direct/P31>  <http://www.wikidata.org/entity/Q11424> .
                 optional {
                   ?film   <http://www.wikidata.org/prop/direct/P577>  ?date .
                   BIND(year(?date) AS ?year)
                 }
                 optional {
                   ?film <http://www.wikidata.org/prop/direct/P136>  ?genre .
                 }
              } group by ?film              
          }

        } GROUP BY ?year1 ?genre1

1 Ответ

1 голос
/ 03 мая 2019

Похоже, что запрос работает после замены двух IF выражений простым sample (который выбирает произвольное значение из группы):

    (sample(?year) as ?year1)
    (sample(?genre) as ?genre1) 

Таким образом, представляется, что затраты на group_concat это главная проблема.Я не нахожу это очень интуитивно понятным и не имеющим объяснений.

Возможно, версия с sample достаточно хороша или, по крайней мере, может дать вам базовую точку для дальнейших улучшений.

...