diff options
author | Jeremy Benoist <jeremy.benoist@gmail.com> | 2019-06-05 10:51:06 +0200 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2019-06-05 10:53:15 +0200 |
commit | 70df4c335965a9562cc24d3ccea0a6ed1a23b7b1 (patch) | |
tree | a0c398645e5d340940cf25fab9cab46eb7903e86 | |
parent | f3bfb875e94021a93e24a41fbc0f8d86d4dee378 (diff) | |
download | wallabag-70df4c335965a9562cc24d3ccea0a6ed1a23b7b1.tar.gz wallabag-70df4c335965a9562cc24d3ccea0a6ed1a23b7b1.tar.zst wallabag-70df4c335965a9562cc24d3ccea0a6ed1a23b7b1.zip |
Use two indexes instead of one for hashed urls
When using `OR` in a where clause, a composite index can't be used. We should use a `UNION` to take advantages of it.
Instead, create 2 indexes on each hashed urls and make 2 queries to find an url. It'll be faster than the previous solution.
4 files changed, 20 insertions, 25 deletions
diff --git a/app/DoctrineMigrations/Version20190601125843.php b/app/DoctrineMigrations/Version20190601125843.php index 341d64dc..0e97606e 100644 --- a/app/DoctrineMigrations/Version20190601125843.php +++ b/app/DoctrineMigrations/Version20190601125843.php | |||
@@ -30,27 +30,8 @@ class Version20190601125843 extends WallabagMigration | |||
30 | ]); | 30 | ]); |
31 | } | 31 | } |
32 | 32 | ||
33 | $entryTable->dropIndex('hashed_url_user_id'); | 33 | // 40 = length of sha1 field hashed_given_url |
34 | $entryTable->addIndex( | 34 | $entryTable->addIndex(['user_id', 'hashed_given_url'], 'hashed_given_url_user_id', [], ['lengths' => [null, 40]]); |
35 | [ | ||
36 | 'user_id', | ||
37 | 'hashed_url', | ||
38 | 'hashed_given_url', | ||
39 | ], | ||
40 | 'hashed_urls_user_id', | ||
41 | [], | ||
42 | [ | ||
43 | // specify length for index which is required by MySQL on text field | ||
44 | 'lengths' => [ | ||
45 | // user_id | ||
46 | null, | ||
47 | // hashed_url | ||
48 | 40, | ||
49 | // hashed_given_url | ||
50 | 40, | ||
51 | ], | ||
52 | ] | ||
53 | ); | ||
54 | } | 35 | } |
55 | 36 | ||
56 | /** | 37 | /** |
@@ -68,7 +49,6 @@ class Version20190601125843 extends WallabagMigration | |||
68 | $entryTable->dropColumn('hashed_given_url'); | 49 | $entryTable->dropColumn('hashed_given_url'); |
69 | } | 50 | } |
70 | 51 | ||
71 | $entryTable->dropIndex('hashed_urls_user_id'); | 52 | $entryTable->dropIndex('hashed_given_url_user_id'); |
72 | $entryTable->addIndex(['user_id', 'hashed_url'], 'hashed_url_user_id', [], ['lengths' => [null, 40]]); | ||
73 | } | 53 | } |
74 | } | 54 | } |
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index 304dd1b3..19f81c0f 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -27,7 +27,8 @@ use Wallabag\UserBundle\Entity\User; | |||
27 | * indexes={ | 27 | * indexes={ |
28 | * @ORM\Index(name="created_at", columns={"created_at"}), | 28 | * @ORM\Index(name="created_at", columns={"created_at"}), |
29 | * @ORM\Index(name="uid", columns={"uid"}), | 29 | * @ORM\Index(name="uid", columns={"uid"}), |
30 | * @ORM\Index(name="hashed_urls_user_id", columns={"user_id", "hashed_url", "hashed_given_url"}, options={"lengths"={null, 40, 40}}) | 30 | * @ORM\Index(name="hashed_url_user_id", columns={"user_id", "hashed_url"}, options={"lengths"={null, 40}}), |
31 | * @ORM\Index(name="hashed_given_url_user_id", columns={"user_id", "hashed_given_url"}, options={"lengths"={null, 40}}) | ||
31 | * } | 32 | * } |
32 | * ) | 33 | * ) |
33 | * @ORM\HasLifecycleCallbacks() | 34 | * @ORM\HasLifecycleCallbacks() |
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 8b29aad2..7772e0b7 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -366,9 +366,20 @@ class EntryRepository extends EntityRepository | |||
366 | */ | 366 | */ |
367 | public function findByHashedUrlAndUserId($hashedUrl, $userId) | 367 | public function findByHashedUrlAndUserId($hashedUrl, $userId) |
368 | { | 368 | { |
369 | // try first using hashed_url (to use the database index) | ||
369 | $res = $this->createQueryBuilder('e') | 370 | $res = $this->createQueryBuilder('e') |
370 | ->where('e.hashedUrl = :hashed_url')->setParameter('hashed_url', $hashedUrl) | 371 | ->where('e.hashedUrl = :hashed_url')->setParameter('hashed_url', $hashedUrl) |
371 | ->orWhere('e.hashedGivenUrl = :hashed_given_url')->setParameter('hashed_given_url', $hashedUrl) | 372 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) |
373 | ->getQuery() | ||
374 | ->getResult(); | ||
375 | |||
376 | if (\count($res)) { | ||
377 | return current($res); | ||
378 | } | ||
379 | |||
380 | // then try using hashed_given_url (to use the database index) | ||
381 | $res = $this->createQueryBuilder('e') | ||
382 | ->where('e.hashedGivenUrl = :hashed_given_url')->setParameter('hashed_given_url', $hashedUrl) | ||
372 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) | 383 | ->andWhere('e.user = :user_id')->setParameter('user_id', $userId) |
373 | ->getQuery() | 384 | ->getQuery() |
374 | ->getResult(); | 385 | ->getResult(); |
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php index a6fd3fff..e9c12c49 100644 --- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php | |||
@@ -265,6 +265,9 @@ class EntryControllerTest extends WallabagCoreTestCase | |||
265 | $this->assertContains('/view/', $client->getResponse()->getTargetUrl()); | 265 | $this->assertContains('/view/', $client->getResponse()->getTargetUrl()); |
266 | } | 266 | } |
267 | 267 | ||
268 | /** | ||
269 | * This test will require an internet connection. | ||
270 | */ | ||
268 | public function testPostNewOkUrlExistWithRedirection() | 271 | public function testPostNewOkUrlExistWithRedirection() |
269 | { | 272 | { |
270 | $this->logInAs('admin'); | 273 | $this->logInAs('admin'); |