Czy istnieje wada korzystania z wp_defer_term_counting?

11

Mam bazę danych WordPress z ponad 2 milionami postów. Ilekroć wstawiam nowy post, muszę zadzwonić, wp_set_object_termsco zajmuje ponad dwie sekundy. Natrafiłem na ten post, który zaleca dzwonienie, wp_defer_term_countingaby pominąć liczenie terminów.

Czy korzystanie z tego podejścia wiąże się z poważnymi konsekwencjami dla funkcjonowania WordPress?

Oto kod z postu na wypadek, gdyby link zginął:

function insert_many_posts(){
  wp_defer_term_counting(true);
  $tasks = get_default_tasks(); 
  for ($tasks as $task){
     $post = array(
       'post_title' => $task[content],
       'post_author' => $current_user->ID,
       'post_content' => '',
       'post_type' => 'bpc_default_task',
       'post_status' => 'publish'
     );
     $task_id = wp_insert_post( $post );

     if ( $task[category] )
        //Make sure we're passing an int as the term so it isn't mistaken for a slug
        wp_set_object_terms( $task_id, array( intval( $category ) ), 'bpc_category' );
  }
}
KalenGi
źródło

Odpowiedzi:

8

Oto kilka przemyśleń na ten temat, ale proszę zauważyć, że nie jest to w żadnym wypadku rozstrzygająca odpowiedź, ponieważ mogą istnieć pewne rzeczy, które przeoczyłem, jednak powinno to dać wgląd w potencjalne problemy.


Tak, technicznie może to mieć konsekwencje.

Wywołanie wp_defer_term_counting(true)staje się naprawdę korzystne, gdy na przykład wykonuje się masowe wstawianie do bazy danych postów i przypisuje terminy do każdego obiektu w ramach procesu.

W takim przypadku wykonaj następujące czynności:

wp_defer_term_counting(true); //defer counting terms

//mass insertion or posts and assignment of terms here

wp_defer_term_counting(false); //count terms after completing business logic

Teraz w twoim przypadku, jeśli wstawiasz tylko jeden post na raz, wówczas odroczenie liczenia terminów będzie nadal korzystne, ale nie zadzwonisz wp_defer_term_counting(false)po tym, jak operacja może pozostawić ciebie i / lub inne strony zaangażowane w żądanie, jeśli polegasz na liczba terminów dla dowolnej innej logiki / przetwarzania, warunkowej lub innej.

Aby wyjaśnić dalej, powiedzmy, że wykonujesz następujące czynności:

Załóżmy, że w ramach tak zwanej taksonomii mamy 3 terminy product_cat, identyfikatorami tych terminów są odpowiednio 1 (nazwa terminu A), 2 (nazwa terminu B) i 3 (nazwa terminu C).

Każdy z powyższych terminów ma już liczbę terminów 5(tylko dla przykładu).

To się dzieje ...

wp_defer_term_counting(true); //defer counting terms

$post_id = wp_insert_post($data);

wp_set_object_terms($post_id, array(1, 2, 3), 'product_cat');

Następnie w swojej logice decydujesz się pobrać ten termin, ponieważ chcesz ocenić liczbę obiektów powiązanych z tym terminem i wykonać inną akcję na podstawie wyniku.

Więc robisz to ...

$terms = get_the_terms($post_id, 'product_cat');

//let's just grab the first term object off the array of returned results
//for the sake of this example $terms[0] relates to term_id 1 (A)
echo $terms[0]->count; //result 5

//dump output of $terms above
array (
  0 => 
  WP_Term::__set_state(array(
     'term_id' => 1,
     'name' => 'A',
     'slug' => 'a',
     'term_group' => 0,
     'term_taxonomy_id' => 1,
     'taxonomy' => 'product_cat',
     'description' => '',
     'parent' => 0,
     'count' => 5, //notice term count still equal to 5 instead of 6
     'filter' => 'raw',
  )),
)

W naszym przykładzie powiedzieliśmy, że nazwa A (term_id 1) ma już 5 powiązanych z nią obiektów, innymi słowy ma już liczbę 5.

Oczekujemy więc, że countparametr na zwróconym obiekcie powyżej będzie wp_defer_term_counting(false)wynosił 6, ale ponieważ nie zadzwoniłeś po operacji, liczniki terminów nie zostały zaktualizowane dla terminów mających zastosowanie (termin A, B lub C).

Dlatego jest to konsekwencja dzwonienia wp_defer_term_counting(true)bez dzwonienia wp_defer_term_counting(false)po operacji.

Teraz pytanie brzmi: czy to na ciebie wpływa? Co się stanie, jeśli nie będziesz musiał dzwonić get_the_termsani wykonywać akcji, która pobierze termin, w którym przez countwartość możesz wykonać inną operację? Cóż, w takim razie świetnie, nie ma dla ciebie problemu .

Ale ... co jeśli ktoś inny jest uzależniony od set_object_termsdziałania w wp_set_object_terms()funkcji i opiera się na poprawności wyrażenia? Teraz widzisz, gdzie mogą wystąpić konsekwencje.

A co, jeśli po zakończeniu żądania zostanie wykonane inne żądanie, które pobiera termin taksonomii i wykorzystuje countwłaściwość w swojej logice biznesowej? To może być problem.

Choć może wydawać się zbyt daleko idące, że countwartości mogą być bardzo szkodliwe, nie możemy zakładać, w jaki sposób takie dane będą wykorzystywane w oparciu o naszą własną filozofię.

Również, jak wspomniano w alternatywnej odpowiedzi, liczba widoczna w tabeli listy systematyki również nie zostanie zaktualizowana.

W rzeczywistości jedynym sposobem na aktualizację zliczeń terminów po odroczeniu zliczania terminów i zakończeniu żądania jest ręczne wywołanie wp_update_term_count($terms, $taxonomy)lub poczekanie, aż ktoś doda termin dla danej taksonomii albo za pomocą interfejsu taksonomii, albo programowo.

Jedzenie do namysłu.

Adam
źródło
1
Myślę, że podsumowujesz to genialnie. Wszystko zależy od tego, czy zamierzasz skorzystać z faktycznego liczenia terminów, o ile mogę odebrać przeglądanie pokrewnego kodu źródłowego
Pieter Goosen
3
Tak, myślałem, że to interesujące pytanie, więc musiałem kopać głębiej ... wydaje się, że jedynym problemem jest to, czy potrzebujesz dokładnej liczby terminów podczas tego samego żądania, a nawet po jego zakończeniu. Pomyśl o tym, jeśli ktoś kiedykolwiek polega na liczeniu terminów dla jakiejkolwiek poważnej logiki biznesowej, to nie można zagwarantować, że to, na co patrzysz, jest w rzeczywistości prawidłowe. Trzeba będzie ręcznie spróbować zaktualizować liczbę (np. wp_update_term_count()) Przed użyciem jej wartości. Nie miałem pojęcia, że ​​tak będzie.
Adam
Bardzo wyczerpująca odpowiedź. Ponieważ tak naprawdę robię wstawkę masową, z tego, co wyjaśniłeś, muszę później przejrzeć warunki i wywołać wp_update_term_count($terms, $taxonomy)każdą z nich, prawda?
KalenGi
2
WordPress nigdy nie zawodzi, powodując niegrzeczne przebudzenie. Muszę przyznać, że czasem można dowiedzieć się więcej na takie pytania, niż po prostu ogarnięcie się w ogóle ;-)
Pieter Goosen
1
Jeśli robisz wkładkę masowej, chciałbym tylko wp_defer_term_counting(true), DO MASS INSERT potem wp_defer_term_counting(false). Jedynym powodem, dla którego zadzwonisz wp_update_term_count()bezpośrednio, jest to, że jeśli zapisałeś term_ids w stanie przejściowym, a następnie odroczysz całkowicie liczenie, ale na przykład odpalisz żądanie AJAX za kulisami, weź obiekt przejściowy, a następnie ręcznie zadzwoń wp_update_term_count()lub użyj zadania cron lub podobnego. Jeśli jesteś w tym samym żądaniu (przed całkowitym zakończeniem wykonania), to i tak wywołuj wp_defer_term_counting(false)połączenia wp_update_term_count()pod maską.
Adam
0

To powinno być względnie bezpieczne jako operacja. Odracza to zliczanie terminów pojawiających się na stronie Edytuj taksonomię. Nie wydaje się więc, aby miały poważne konsekwencje.

phatskat
źródło