20260429100000_add_ip_text_indexes.php 1.0 KB

1234567891011121314151617181920212223242526272829303132333435
  1. <?php
  2. declare(strict_types=1);
  3. use App\Infrastructure\Db\Migrations\BaseMigration;
  4. /**
  5. * SPEC §M09.5: index `ip_text` so the admin IP search ("`q=` substring or
  6. * prefix match") doesn't fall back to a full-table scan.
  7. *
  8. * `ip_scores.ip_text` is the primary search column (the search results are
  9. * grouped by IP). `reports.ip_text` is denormalised alongside `ip_bin`
  10. * but the search joins by `ip_bin`, so we don't add an index there.
  11. *
  12. * `LIKE 'prefix%'` uses the index on default-collation columns on both
  13. * SQLite and MySQL; `LIKE '%substr%'` falls back to a scan, which is
  14. * acceptable at the dataset sizes we expect (the search caps at 200
  15. * rows per page).
  16. */
  17. final class AddIpTextIndexes extends BaseMigration
  18. {
  19. public function up(): void
  20. {
  21. $this->table('ip_scores')
  22. ->addIndex(['ip_text'], ['name' => 'idx_ip_scores_ip_text'])
  23. ->update();
  24. }
  25. public function down(): void
  26. {
  27. $this->table('ip_scores')
  28. ->removeIndexByName('idx_ip_scores_ip_text')
  29. ->update();
  30. }
  31. }