## Compiler magic

22 février 2017

How do you efficiently divide by 19? All you need is some compiler magic!  It’s all explained here!

## 1001001 SOS

10 février 2017

I’ve been dealing a lot with bit operations lately.  And doing lots of benchmarking, like here. As I was looking for a bit count method in Pharo (it used to be there but it no longer exists in Pharo 5.0), I got curious about the many different versions of bit counting algorithms I could find on the internet.

What’s so special about bit operations you ask?  Not much.  Except when you have to do it really fast on 64bit integers!  Like in a chess program!  Millions of times per position. So instead of copying the #bitCount method that was in Squeak, I decided I’d have a look at what is available on the net…

So I decided to share what I found.  This could potentially be useful for people who have to deal with bit counting a lot. Especially if you deal with 14 bits or less!

Here’s a typical run of the different bit counting algorithms I have tested on Squeak 5.1 64bit.

```Number of [myBitCount1 (128 bits)] per second: 0.061M
Number of [myBitCount1 (14 bits)] per second: 1.417M
Number of [myBitCount1 (16 bits)] per second: 1.271M
Number of [myBitCount1 (30 bits)] per second: 0.698M
Number of [myBitCount1 (32 bits)] per second: 0.651M
Number of [myBitCount1 (60 bits)] per second: 0.362M
Number of [myBitCount1 (64 bits)] per second: 0.131M
Number of [myBitCount1 (8 bits)] per second: 2.255M
Number of [myBitCount2 (128 bits)] per second: 0.286M
Number of [myBitCount2 (14 bits)] per second: 3.623M
Number of [myBitCount2 (16 bits)] per second: 3.630M
Number of [myBitCount2 (30 bits)] per second: 2.320M
Number of [myBitCount2 (32 bits)] per second: 2.336M
Number of [myBitCount2 (60 bits)] per second: 1.415M
Number of [myBitCount2 (64 bits)] per second: 1.208M
Number of [myBitCount2 (8 bits)] per second: 4.950M
Number of [myBitCount3 (128 bits)] per second: 0.498M
Number of [myBitCount3 (14 bits)] per second: 4.556M
Number of [myBitCount3 (16 bits)] per second: 4.673M
Number of [myBitCount3 (30 bits)] per second: 3.401M
Number of [myBitCount3 (32 bits)] per second: 3.401M
Number of [myBitCount3 (60 bits)] per second: 2.130M
Number of [myBitCount3 (64 bits)] per second: 1.674M
Number of [myBitCount3 (8 bits)] per second: 4.938M
Number of [myBitCount4 (128 bits)] per second: 0.041M
Number of [myBitCount4 (14 bits)] per second: 5.333M
Number of [myBitCount4 (16 bits)] per second: 4.819M
Number of [myBitCount4 (30 bits)] per second: 2.841M
Number of [myBitCount4 (32 bits)] per second: 2.674M
Number of [myBitCount4 (60 bits)] per second: 1.499M
Number of [myBitCount4 (64 bits)] per second: 0.270M
Number of [myBitCount4 (8 bits)] per second: 7.435M
Number of [myBitCount5 (128 bits)] per second: 0.377M
Number of [myBitCount5 (14 bits)] per second: 3.937M
Number of [myBitCount5 (16 bits)] per second: 3.035M
Number of [myBitCount5 (30 bits)] per second: 2.137M
Number of [myBitCount5 (32 bits)] per second: 2.035M
Number of [myBitCount5 (60 bits)] per second: 1.386M
Number of [myBitCount5 (64 bits)] per second: 1.188M
Number of [myBitCount5 (8 bits)] per second: 4.167M
Number of [myBitCount6 (128 bits)] per second: 0.381M
Number of [myBitCount6 (14 bits)] per second: 5.195M
Number of [myBitCount6 (16 bits)] per second: 3.552M
Number of [myBitCount6 (30 bits)] per second: 2.488M
Number of [myBitCount6 (32 bits)] per second: 2.364M
Number of [myBitCount6 (60 bits)] per second: 1.555M
Number of [myBitCount6 (64 bits)] per second: 1.284M
Number of [myBitCount6 (8 bits)] per second: 5.571M
Number of [myPopCount14bit (14 bits)] per second: 18.349M
Number of [myPopCount14bit (8 bits)] per second: 18.519M
Number of [myPopCount24bit (14 bits)] per second: 7.407M
Number of [myPopCount24bit (16 bits)] per second: 7.463M
Number of [myPopCount24bit (8 bits)] per second: 7.018M
Number of [myPopCount32bit (14 bits)] per second: 4.963M
Number of [myPopCount32bit (16 bits)] per second: 5.013M
Number of [myPopCount32bit (30 bits)] per second: 4.608M
Number of [myPopCount32bit (32 bits)] per second: 4.619M
Number of [myPopCount32bit (8 bits)] per second: 4.608M
Number of [myPopCount64a (14 bits)] per second: 2.778M
Number of [myPopCount64a (16 bits)] per second: 2.793M
Number of [myPopCount64a (30 bits)] per second: 2.751M
Number of [myPopCount64a (32 bits)] per second: 2.703M
Number of [myPopCount64a (60 bits)] per second: 2.809M
Number of [myPopCount64a (64 bits)] per second: 1.385M
Number of [myPopCount64a (8 bits)] per second: 2.755M
Number of [myPopCount64b (14 bits)] per second: 3.063M
Number of [myPopCount64b (16 bits)] per second: 3.096M
Number of [myPopCount64b (30 bits)] per second: 3.106M
Number of [myPopCount64b (32 bits)] per second: 3.053M
Number of [myPopCount64b (60 bits)] per second: 3.008M
Number of [myPopCount64b (64 bits)] per second: 1.444M
Number of [myPopCount64b (8 bits)] per second: 3.091M
Number of [myPopCount64c (14 bits)] per second: 1.625M
Number of [myPopCount64c (16 bits)] per second: 1.600M
Number of [myPopCount64c (30 bits)] per second: 1.542M
Number of [myPopCount64c (32 bits)] per second: 1.529M
Number of [myPopCount64c (60 bits)] per second: 1.566M
Number of [myPopCount64c (64 bits)] per second: 1.082M
Number of [myPopCount64c (8 bits)] per second: 3.945M
```

Now, since method #myBitCount2 is similar to the #bitCount method in Squeak, that means there is still place for improvement as far as a faster #bitCount is needed.  Now the question is : do we optimize it for the usual usage (SmallInteger), for 64bit integer or we use an algorithm that performs relatively well in most cases?  Obviously, since I will always be working with 64bit positive integers, I have the luxury to pick a method that precisely works best in my specific case!

All test code I have used can be found here.

Note: Rush fans have probably noticed the reference in the title…

## Bits and Pieces

10 février 2017

Often times, we take stuff for granted.  But while preparing to embark on a crazy project (description in French here and Google translation in English here), I wanted to benchmark the bit manipulation operations in both Squeak and Pharo, for the 32bit and 64bit images (I am on Windows so the 64bit VM is not available for testing yet but it’ll come!).  So essentially, it was just a test to compare the VM-Image-Environment combo!

To make a long story short, I was interested in testing the speed of 64bit operations on positive integers for my chess program. I quickly found some cases where LargePositiveInteger operations were more than 7-12 times slower than the SmallInteger equivalences and I became curious since it seemed like a lot.  After more testing and discussions (both offline and online), someone suggested that some LargePositiveInteger operations could possibly be slow because they were not inlined in the JIT.  It was then recommended that I override those methods in LargePositiveInteger (with primitives 34 to 37), thus shortcutting the default and slow methods in Integer (corresponding named primitives, primDigitBitAnd, primDigitBitOr, primDigitBitXorprimDigitBitShiftMagnitude in LargeIntegers module).  I immediately got a 2-3x speedup for LargePositiveInteger but…

Things have obviously changed in the Squeak 64bit image since some original methods (in class Integer) like #bitAnd: and #bitOr: are way faster than the overrides (in class LargePositiveInteger )!  Is it special code in the VM that checks for 32bit vs 64bit (more precisely, 30bit vs 60bit integers)?  Is it in the LargeIntegers module?

Here are 2 typical runs for Squeak 5.1 32bit (by the way, Pharo 32bit image performs similarly) and Squeak 5.1 64bit images  :

Squeak 5.1 32bit

```Number of #allMask: per second: 7.637M
Number of #anyMask: per second: 8.333M
Number of #bitAnd: per second: 17.877M
Number of #bitAnd2: per second: 42.105M
Method #bitAnd2: seems to work properly! Overide of #bitAnd: in LargeInteger works!
Number of #bitAt: per second: 12.075M
Number of #bitAt:put: per second: 6.287M
Number of #bitClear: per second: 6.737M
Number of #bitInvert per second: 5.536M
Number of #bitOr: per second: 15.764M
Number of #bitOr2: per second: 34.409M
Method #bitOr2: seems to work properly! Overide of #bitOr: in LargeInteger works!
Method #bitShift2: (left & right shifts) seems to work properly! Overide of #bitShift: in LargeInteger works!
Number of #bitXor: per second: 15.385M
Number of #bitXor2: per second: 34.043M
Method #bitXor2: seems to work properly! Overide of #bitXor: in LargeInteger works!
Number of #highBit per second: 12.451M
Number of #<< per second: 6.517M
Number of #bitLeftShift2: per second: 8.399M
Number of #lowBit per second: 10.702M
Number of #noMask: per second: 7.064M
Number of #>> per second: 7.323M
Number of #bitRightShift2: per second: 29.358M
```

Squeak 5.1 64bit

```Number of #allMask: per second: 36.782M
Number of #anyMask: per second: 41.026M
Number of #bitAnd: per second: 139.130M
Number of #bitAnd2: per second: 57.143M
Method #bitAnd2: seems to work properly! Overide of #bitAnd: in LargeInteger works!
Number of #bitAt: per second: 23.358M
Number of #bitAt:put: per second: 8.649M
Number of #bitClear: per second: 38.554M
Number of #bitInvert per second: 29.630M
Number of #bitOr: per second: 139.130M
Number of #bitOr2: per second: 58.182M
Method #bitOr2: seems to work properly! Overide of #bitOr: in LargeInteger works!
Method #bitShift2: (left & right shifts) seems to work properly! Overide of #bitShift: in LargeInteger works!
Number of #bitXor: per second: 55.172M
Number of #bitXor2: per second: 74.419M
Method #bitXor2: seems to work properly! Overide of #bitXor: in LargeInteger works!
Number of #highBit per second: 7.921M
Number of #<< per second: 10.127M
Number of #bitLeftShift2: per second: 12.800M
Number of #lowBit per second: 6.823M
Number of #noMask: per second: 39.024M
Number of #>> per second: 23.188M
Number of #bitRightShift2: per second: 56.140M
```

So now, I’m left with 2 questions :

1. Why exactly does the override work (in 32bit images)?
2. What changed so that things are different in Squeak 5.1 64bit image (overrides partially work)?

If you’re curious/interested, the code I have used to test is here.

Leave me a comment (or email) if you have an explanation!

To be continued…

## Freewill in progress (2)

3 août 2016

(Click to enlarge)

What’s up?

As you can see, Freewill now supports 17 different selection policies.  At this point, all of them are coded but only half of them have been tested.

The 11 available termination policies are coded, half of them tested.

So far, only 2 mutation policies are available.  Both of them are coded and tested. I will probably need a few extras for TSP type of problems as well as numerically parametrized problems (e.g. De Jong functions with a domain for each variable).  I’ll probably add 3-4 other ones specific to the problem that started all this adventure!

Only one immigration policy (no immigration!) is available and it will stay that way for a long time.  I’ll wait until I am hyper confident that this framework is rock solid before introducing parallelism and exchange of individuals between « islands » (i.e. simulations).  This one is a faaaaaaar away!

Six crossover policies are available as of now .  This area will require some (minor I think at first glance) changes for the TSP type of problems : not quite decided on the approach I will take to solve this.  Since crossover is often very problem/chromosome specific, I’ll probably delay those change until the end, once I have all examples coded and ready to be tested to have a better idea of what is needed.  But I will definitely add a few (3-4) crossover policies tailored for the Ruzzle problem.

I have solved the discrepancy (see here and here) between my results and the TSPLIB ones regarding the tour length of the Burma14 problem.  Will probably add a lot bigger TSP problem to see how the framework can handle an extremely huge search space! Oh!  And I need to clean up all the crap I added/modified while looking for the problem of « distance difference » : 2 classes were butchered in the process!

I need to add a few « crash test dummy » classes to test all those different selection policies (and crossover) in a simpler and more efficient manner!  Or I should kick myself in the %*&#\$!@ and code the « bits » example classes…

I will soon work on a customizable display of statistics.  All that’s needed is already there, it’s just a matter of gluing everything together!

Once I’m done with the 8 queens problems, I’ll attack the numerically parametrized problems.  Will probably have 2-3 examples (from De Jong functions) as well as the INSANE Griewank function.

The classes used for randomly choosing the next parent chromosomes as well as scaling/ranking can be optimized.  But since they just work great since day 1, I’ll keep that for the very end.  But I know they can be a lot faster than what they are right now.

I also plan on having a very basic export mechanism so I can dump all those ruzzle chromosomes in a MySQL database to be able to do some reporting and study the various policies and their effects.

I started adding comments to the classes, mostly to keep references, maintain a todo list per class and add some notes for myself to quickly remember why things work that way!

I’ll probably have an image by tomorrow that will run simulations for the ruzzle problem full-time. I wanna beat that record!

## Les casse-tête

24 janvier 2016

Ceux qui me connaissent bien le savent, j’adore me casser la tête sur une foule de « petits » problèmes (mathématiques, algorithmiques ou autres) : ça permet de garder le cerveau en forme et ça me donne une occasion de faire du Smalltalk et de me garder à jour dans mes skills autant de programmation que d’analyse.

Si vous êtes comme moi, voici une liste de ces petits casse-tête qui m’amusent en ce moment (ou depuis un bout) et qui pourrait vous servir de suggestions…

Les nombres de Lychrel

Avant tout, un peu de vocabulaire!

Un palindrome est une mot, une phrase ou un nombre qui s’écrit de la même façon à l’endroit et à l’envers.  Par exemple, Laval, Bob ou 17371.  Ça peut également être une phrase ou un bout de texte comme « Mon nom » ou le célèbre « A man, a plan, a canal: Panama ».

Grosso modo, un nombre de Lychrel est un nombre qui ne peut pas former de nombre palindrome lorsqu’on l’additionne à répétition avec son « inverse ».

Par exemple, 59 n’est pas un nombre de Lychrel puis qu’on aboutit à un palindrome au bout des itérations suivantes:

59 + 95 = 154
154 + 451 = 605
605 + 506 = 1111

L’histoire devient passionnante quand des mathématiciens se sont intéressés au plus petit nombre pour lequel on n’a pas encore trouvé de nombre palindrome après une quantité anormalement élevée d’itérations.  Il s’agit de 196.

Le problème est fascinant en soi de par la simplicité des opérations impliquées (des additions et la détection de palindrome) et les raccourcis et astuces nécessaires (autant mathématiques qu’algorithmiques) pour tenter de le résoudre.

Parmi les incontournables sur le sujet, il y a les sites de Jason Doucet et celui de Wade VanLandingham.

Le site What If?

Un site de questions absurdes avec des explications sérieuses et scientifiques.  Un challenge pour le cerveau quand on essaie de formuler une réponse aux problèmes présentés! Ce qui est intéressant, c’est le raisonnement et les arguments des réponses à des problèmes aussi hypothétiques que, bien souvent, idiots!  Comme celui-ci par exemple.

La persistence multiplicative

On définit grossièrement la persistence multiplicative par le nombre de fois qu’on peut multiplier les chiffres d’un nombre entre eux jusqu’à ce que le résultat ne comporte qu’un seul chiffre.

Par exemple:

679 ->  6 * 7 * 9 = 378
378 ->  3 * 7 * 8 = 168
168 ->  1 * 6 * 8 = 48
48 ->  4 * 8 = 32
32 ->  3 * 2 = 6

On dira donc que le nombre 679 a une persistence multiplicative de 5.

À ce jour, nous ne connaissons aucun nombre en deça de 10^233 (10 à la puissance 233) ayant une persistence multiplicative supérieure à 11. C’est précisément cette limite qui intéresse les mathématiciens!

Évidemment, ce qu’il est intéressant de chercher ce sont les nombres dits candidats.  Tout nombre comportant un 0 est éliminé d’office (ça occasionne forcément un résultat de zéro). Comme la multiplication par 1 n’apporte rien de plus, on ne considérera que les nombres sans le chiffre 1.  De plus, on éliminera les nombres comportant à la fois le chiffre 5 et un nombre pair comme cela produira un multiple de 10, donc un résultat de zéro.

Pour un bref aperçu de la persistence multiplicative, il y a une page de Wolfram sur le sujet. Pour un résumé des optimisations et trucs possibles, il y a ce papier.

La conjecture de Collatz

Un autre problème mathématique non résolu : la conjecture de Collatz (aussi appelée conjecture de Syracuse).

Si vous avez quelques cycles de CPU à partager, il existe un projet BOINC juste ici.

Autrement, je vous recommende de lire sur le sujet.  Les diverses astuces pour accélérer les calculs sont aussi surprenantes qu’efficaces!

Euler Project

Un site qui propose des problèmes mathématiques à être résolus par ordinateur!  Il y a un hic!  Il devient assez rapidement évident que la solution est bien souvent (pour ne pas écrire toujours) algébrique et mathématique.

C’est ce dont je me suis encore rendu compte récemment, en scrappant toute une nuit à faire des calculs pour résoudre le problème 131!

Sudoku

Il y a tant d’articles sur le sujet qu’un simple recherche Google devrait suffire à vous tenir occupé en lecture jusqu’à la fin des temps!

Pour ma part, par pur amusement, je me suis attardé à résoudre ces petits problèmes d’une façon surprenante : le préambule, le premier article, la seconde partie et la dernière partie.

Pour un aperçu des techniques de résolution (autres que la force brute), il y a cette liste.

EinStein würfelt nicht!

Communément appelé EWN, ce petit jeu renforme une quantité de particularités contre-intuitives. Autre difficulté, l’aspect probabiliste qui vient tout brouiller les cartes!

Vous pouvez y jouer sur le site de jeux Little Golem si ça vous intéresse.  Pour ma part, je planche sur quelques idées de stratégies que j’entends bien tester avec un programme bientôt.

Ruzzle

Un petit jeu tout simple!  Et pourtant!

J’ai commencé à étudier de plus près le ruzzle comme en témoigne cet article et celui-ci.

Comme je n’ai toujours pas trouvé de grille meilleure que celle de M. Müller, ma quête se poursuit! Des nouvelles pour très bientôt!

## Comment presser un citron (troisième partie)

27 mai 2013

1. Un problème n’arrive jamais seul

Dans la deuxième partie de cet article (le premier article étant ici), nous nous sommes laissés sur un exemple extrême (i.e. une grille avec des lignes et des colonnes vides) afin de vérifier la validité et l’efficacité de la solution présentée dans un des pires scénarios envisageable :

Avant même de débuter, rappelez-vous qu’il est primordial d’exécuter la commande suivante dans votre session pour éviter d’avoir à attendre une éternité, que ce soit pour la requête SQL ou pour un EXPLAIN!

```set @@optimizer_search_depth = 3;
```

Qu’arriverait-il si nous avions à solutionner un sudoku contenant à la fois des lignes et des colonnes vides, comme dans l’exemple ci-haut avec la requête suivante:

```SELECT *
FROM sudoku_combined_view
WHERE
(r2c2 = 3) AND (r2c3 = 4) AND (r2c4 = 8) AND (r2c5 = 2) AND
(r2c6 = 5) AND (r2c7 = 6) AND (r2c8 = 9) AND (r3c2 = 5) AND
(r3c3 = 9) AND (r3c4 = 3) AND (r3c5 = 6) AND (r3c6 = 4) AND
(r3c7 = 1) AND (r3c8 = 8) AND (r4c2 = 9) AND (r4c3 = 7) AND
(r4c4 = 1) AND (r4c5 = 8) AND (r4c6 = 2) AND (r4c7 = 5) AND
(r4c8 = 6) AND (r6c2 = 8) AND (r6c3 = 1) AND (r6c4 = 4) AND
(r6c5 = 7) AND (r6c6 = 6) AND (r6c7 = 2) AND (r6c8 = 3) AND
(r7c2 = 2) AND (r7c3 = 5) AND (r7c4 = 6) AND (r7c5 = 4) AND
(r7c6 = 1) AND (r7c7 = 9) AND (r7c8 = 7) AND (r8c2 = 7) AND
(r8c3 = 6) AND (r8c4 = 5) AND (r8c5 = 3) AND (r8c6 = 8) AND
(r8c7 = 4) AND (r8c8 = 2);
```

Examinons le résultat du EXPLAIN pour la grille en question:

```+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-------------------------------+------+----------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                                                                                                                      | key         | key_len | ref                           | rows | Extra                                                    |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-------------------------------+------+----------------------------------------------------------+
|  1 | SIMPLE      | col3  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i38,i48 | 2,2,2   | NULL                          |   64 | Using intersect(i23,i38,i48); Using where                |
|  1 | SIMPLE      | r2    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i58     | 2,2     | NULL                          |   68 | Using intersect(i23,i58); Using where; Using join buffer |
|  1 | SIMPLE      | r3    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i78,i56     | 2,2     | NULL                          |   68 | Using intersect(i78,i56); Using where; Using join buffer |
|  1 | SIMPLE      | r4    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i38,i46     | 2,2     | NULL                          |   68 | Using intersect(i38,i46); Using where; Using join buffer |
|  1 | SIMPLE      | r6    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i67     | 2,2     | NULL                          |   68 | Using intersect(i23,i67); Using where; Using join buffer |
|  1 | SIMPLE      | r7    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i38,i56     | 2,2     | NULL                          |   68 | Using intersect(i38,i56); Using where; Using join buffer |
|  1 | SIMPLE      | r8    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer |
|  1 | SIMPLE      | col2  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer |
|  1 | SIMPLE      | col4  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i78,i46     | 2,2     | NULL                          |   68 | Using intersect(i78,i46); Using where; Using join buffer |
|  1 | SIMPLE      | col5  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer |
|  1 | SIMPLE      | col6  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i67     | 2,2     | NULL                          |   68 | Using intersect(i23,i67); Using where; Using join buffer |
|  1 | SIMPLE      | col7  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer |
|  1 | SIMPLE      | col8  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i24     | 2,2     | NULL                          |   68 | Using intersect(i37,i24); Using where; Using join buffer |
|  1 | SIMPLE      | col1  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23         | 2       | sudoku.r2.c1,sudoku.r3.c1     | 5040 | Using where                                              |
|  1 | SIMPLE      | r1    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.col1.c1,sudoku.col2.c1 | 5040 | Using where                                              |
|  1 | SIMPLE      | r5    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.col1.c5,sudoku.col2.c5 | 5040 | Using where                                              |
|  1 | SIMPLE      | r9    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.col1.c9,sudoku.col2.c9 | 5040 | Using where                                              |
|  1 | SIMPLE      | col9  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.r1.c9,sudoku.r2.c9     | 5040 | Using where                                              |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-------------------------------+------+----------------------------------------------------------+
18 rows in set (0.20 sec)```

À première vue, tout semble correct! Aucun table scan et les indexes sont utilisés pour chaque colonne et chaque rangée non vide!

Et en combien de temps MySQL peut-il « solutionner » cette grille ?

Fantastique!  1.5 seconde!  Tout est réglé!  Malheureusement, non…

2. Le pire scénario possible

Il existe une catégorie de sudokus que nombre de mathématiciens et d’informaticiens étudient depuis des années : ces grilles minimales n’ont seulement que 17 révélés, le minimum théorique (une conjecture encore non prouvée de façon mathématique par Gary McGuire, Bastian Tugemann et Gilles Civario, un autre intéressant article ici) pouvant mener à une solution unique.  Plusieurs de ces grilles spéciales (17 révélés) sont depuis des années compilées par Gordon Royle, professeur à l’université d’Australie Occidentale.

Comme celle-ci :

Vous remarquerez que cette grille ne contient aucune ligne ni aucune colonne vide! Essayons donc de voir en combien de temps MySQL pourra résoudre celle-ci :

```mysql> SELECT *
-> FROM sudoku_combined_view
-> WHERE
-> (r1c8 = 1) AND
-> (r2c1 = 4) AND
-> (r3c2 = 2) AND
-> (r4c5 = 5) AND
-> (r4c7 = 4) AND
-> (r4c9 = 7) AND
-> (r5c3 = 8) AND
-> (r5c7 = 3) AND
-> (r6c3 = 1) AND
-> (r6c5 = 9) AND
-> (r7c1 = 3) AND
-> (r7c4 = 4) AND
-> (r7c7 = 2) AND
-> (r8c2 = 5) AND
-> (r8c4 = 1) AND
-> (r9c4 = 8) AND
-> (r9c6 = 6);
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| r1c1 | r1c2 | r1c3 | r1c4 | r1c5 | r1c6 | r1c7 | r1c8 | r1c9 | r2c1 | r2c2 | r2c3 | r2c4 | r2c5 | r2c6 | r2c7 | r2c8 | r2c9 | r3c1 | r3c2 | r3c3 | r3c4 | r3c5 | r3c6 | r3c7 | r3c8 | r3c9 | r4c1 | r4c2 | r4c3 | r4c4 | r4c5 | r4c6 | r4c7 | r4c8 | r4c9 | r5c1 | r5c2 | r5c3 | r5c4 | r5c5 | r5c6 | r5c7 | r5c8 | r5c9 | r6c1 | r6c2 | r6c3 | r6c4 | r6c5 | r6c6 | r6c7 | r6c8 | r6c9 | r7c1 | r7c2 | r7c3 | r7c4 | r7c5 | r7c6 | r7c7 | r7c8 | r7c9 | r8c1 | r8c2 | r8c3 | r8c4 | r8c5 | r8c6 | r8c7 | r8c8 | r8c9 | r9c1 | r9c2 | r9c3 | r9c4 | r9c5 | r9c6 | r9c7 | r9c8 | r9c9 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|   6  |   9  |   3  |   7  |   8  |   4  |   5  |   1  |   2  |   4  |   8  |   7  |   5  |   1  |   2  |   9  |   3  |   6  |   1  |   2  |   5  |   9  |   6  |   3  |   8  |   7  |   4  |   9  |   3  |   2  |   6  |   5  |   1  |   4  |   8  |   7  |   5  |   6  |   8  |   2  |   4  |   7  |   3  |   9  |   1  |   7  |   4  |   1  |   3  |   9  |   8  |   6  |   2  |   5  |   3  |   1  |   9  |   4  |   7  |   5  |   2  |   6  |   8  |   8  |   5  |   6  |   1  |   2  |   9  |   7  |   4  |   3  |   2  |   7  |   4  |   8  |   3  |   6  |   1  |   5  |   9  |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1 row in set (2 min 20.83 sec)
```

Ouch!  Je ne suis pas arrivé à descendre sour la barre des 40 secondes malgré mes tentatives répétées et ce, sur différents serveurs avec différentes configurations (et même différentes autres grilles de 17 révélés). Les résultats pour solutionner cette grille vont de près de 40 secondes à plus de 33 minutes. Le résultat du EXPLAIN parle par lui-même :

```+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+---------+---------+-------------------------------+------+----------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                                                                                                                      | key     | key_len | ref                           | rows | Extra                                                    |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+---------+---------+-------------------------------+------+----------------------------------------------------------+
|  1 | SIMPLE      | r4    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i57,i59 | 2,2     | NULL                          |  624 | Using intersect(i57,i59); Using where                    |
|  1 | SIMPLE      | r7    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i14,i47 | 2,2     | NULL                          |  624 | Using intersect(i14,i47); Using where; Using join buffer |
|  1 | SIMPLE      | col4  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i78,i89 | 2,2     | NULL                          |  624 | Using intersect(i78,i89); Using where; Using join buffer |
|  1 | SIMPLE      | col7  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i45,i47 | 2,2     | NULL                          |  624 | Using intersect(i45,i47); Using where; Using join buffer |
|  1 | SIMPLE      | r8    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i24     | 2       | const,const                   | 5000 | Using where                                              |
|  1 | SIMPLE      | r9    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i46     | 2       | const,const                   | 5001 | Using where                                              |
|  1 | SIMPLE      | col1  | range       | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i27     | 2       | NULL                          | 5000 | Using where; Using join buffer                           |
|  1 | SIMPLE      | r5    | range       | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37     | 2       | NULL                          | 5001 | Using where; Using join buffer                           |
|  1 | SIMPLE      | r6    | range       | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i35     | 2       | NULL                          | 5001 | Using where; Using join buffer                           |
|  1 | SIMPLE      | col3  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i45     | 2       | sudoku.r4.c3,const            | 5040 | Using where                                              |
|  1 | SIMPLE      | col2  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i34     | 2       | const,sudoku.r4.c2            | 5040 | Using where                                              |
|  1 | SIMPLE      | r2    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12     | 2       | const,sudoku.col2.c2          | 5040 | Using where                                              |
|  1 | SIMPLE      | col5  | range       | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i46     | 2       | NULL                          | 5001 | Using where; Using join buffer                           |
|  1 | SIMPLE      | r3    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12     | 2       | sudoku.col1.c3,const          | 5040 | Using where                                              |
|  1 | SIMPLE      | col8  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12     | 2       | const,sudoku.r2.c8            | 5040 | Using where                                              |
|  1 | SIMPLE      | r1    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12     | 2       | sudoku.col1.c1,sudoku.col2.c1 | 5040 | Using where                                              |
|  1 | SIMPLE      | col9  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12     | 2       | sudoku.r1.c9,sudoku.r2.c9     | 5040 | Using where                                              |
|  1 | SIMPLE      | col6  | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12     | 2       | sudoku.r1.c6,sudoku.r2.c6     | 5040 | Using where                                              |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+---------+---------+-------------------------------+------+----------------------------------------------------------+
18 rows in set (2.59 sec)```

Observez la colonne rows dans le résultat du EXPLAIN pour comprendre le nombre astronomique de jointures possibles que MySQL aura à effectuer et à tester…  Dans la très grande majorité des cas, ce chiffre est supérieur à 5000!

Il devient maintenant évident que notre solution ne tient plus la route…

3. Ne pas céder au découragement!

Il existe bon nombre d’autres possibilités d’optimisations que nous n’avons toujours pas envisagées.  Par exemple, dans certains cas il pourrait être avantageux de chercher par boîtes (carré de 3×3 dans le sudoku).  Certaines grilles de 17 révélés pourraient grandement en bénéficier mais il nous faudrait alors joindre 27 tables!  Ce qui est gagné d’un côté est perdu de l’autre.

Nous pourrions également créer des partitions mais dans ce cas, quelles seraient les chances qu’une colonne ou une rangée contienne la donnée permettant de discriminer et de choisir la partition requise?

Nous pourrions augmenter la taille de l’index pour passer de 2 colones à 3 mais l’impact de cette mesure serait inutile pour les grilles de 17 révélés.

Qu’arriverait-il si nous passions du format de table MyISAM à InnoDb ?  Absolument rien, le problème demeure entier : MySQL n’est pas assez rapide pour lire les données (ou les indexes) sur disque puis les joindre efficacement dans un cas aussi extrême.

L’idée à la base de cette série d’article était d’arriver à solutionner un sudoku valide en n’utilisant que du SQL.  Un sudoku valide, par définition, a une seule solution.  Nous aurions pu ajouter LIMIT 1 à chacune de nos vues mais hélas, ce faisant, nos vues seraient contraintes d’utiliser l’algorithme TEMPTABLE au lieu de MERGE, ce qui serait catastrophique!

Évidemment, quelques autres astuces existent, comme augmenter la taille des variables key_buffer_size et join_buffer_size, diminuer la valeur du optimizer_search_depth, etc.  Évidemment dans le cas des 2 premières variables, je ne peux rien vous suggérer comme ces paramètres dépendent de la mémoire RAM disponible sur votre machine, le système d’exploitation utilisé, etc.  Quant à la valeur de la variable optimizer_search_depth, diminuer celle-ci n’aura pas d’impact significatif comme le problème réside dans la lenteur des accès au disque dur et au nombre effarant de jointures et de rangées à examnier (et à retrouver puis lire).

4. Éplucher toutes les options

Il existe un type de table, MEMORY, en MySQL qui nous permettrait d’éviter d’avoir à lire les données (ou les indexes) sur disque, ce qui pourrait avoir un impact majeur dans notre cas.  Nous allons donc créer cette table en mémoire et la remplir tout en créant les indexes nécessaires (exactement les mêmes vues et indexes que la table de format MyISAM).

Mais avant de procéder, prenez bien soin de vous assurez que la variable max_heap_table_size soit supérieure à 216Mb ( 226492416) sinon vous vous heurterez à une tonne d’erreurs 1114 (table full).  Si ce n’est pas le cas, vous pouvez fixer la valeur de cette variable à 216Mb comme suit :

```set @@max_heap_table_size =  226492416;
```

Une fois cette précaution prise, construisez la table et les indexes nécessaires comme suit:

```USE sudoku;

DROP TABLE IF EXISTS positions_memory;
CREATE TABLE positions_memory (
c1 TINYINT UNSIGNED NOT NULL,
c2 TINYINT UNSIGNED NOT NULL,
c3 TINYINT UNSIGNED NOT NULL,
c4 TINYINT UNSIGNED NOT NULL,
c5 TINYINT UNSIGNED NOT NULL,
c6 TINYINT UNSIGNED NOT NULL,
c7 TINYINT UNSIGNED NOT NULL,
c8 TINYINT UNSIGNED NOT NULL,
c9 TINYINT UNSIGNED NOT NULL
) ENGINE=MEMORY;

INSERT INTO positions_memory (c1, c2, c3, c4, c5, c6, c7, c8, c9)
SELECT c1, c2, c3, c4, c5, c6, c7, c8, c9 FROM positions;

CREATE INDEX i12 ON positions_memory(c1, c2) USING HASH; CREATE INDEX i13 ON positions_memory(c1, c3) USING HASH;
CREATE INDEX i14 ON positions_memory(c1, c4) USING HASH; CREATE INDEX i15 ON positions_memory(c1, c5) USING HASH;
CREATE INDEX i16 ON positions_memory(c1, c6) USING HASH; CREATE INDEX i17 ON positions_memory(c1, c7) USING HASH;
CREATE INDEX i18 ON positions_memory(c1, c8) USING HASH; CREATE INDEX i19 ON positions_memory(c1, c9) USING HASH;
CREATE INDEX i23 ON positions_memory(c2, c3) USING HASH; CREATE INDEX i24 ON positions_memory(c2, c4) USING HASH;
CREATE INDEX i25 ON positions_memory(c2, c5) USING HASH; CREATE INDEX i26 ON positions_memory(c2, c6) USING HASH;
CREATE INDEX i27 ON positions_memory(c2, c7) USING HASH; CREATE INDEX i28 ON positions_memory(c2, c8) USING HASH;
CREATE INDEX i29 ON positions_memory(c2, c9) USING HASH; CREATE INDEX i34 ON positions_memory(c3, c4) USING HASH;
CREATE INDEX i35 ON positions_memory(c3, c5) USING HASH; CREATE INDEX i36 ON positions_memory(c3, c6) USING HASH;
CREATE INDEX i37 ON positions_memory(c3, c7) USING HASH; CREATE INDEX i38 ON positions_memory(c3, c8) USING HASH;
CREATE INDEX i39 ON positions_memory(c3, c9) USING HASH; CREATE INDEX i45 ON positions_memory(c4, c5) USING HASH;
CREATE INDEX i46 ON positions_memory(c4, c6) USING HASH; CREATE INDEX i47 ON positions_memory(c4, c7) USING HASH;
CREATE INDEX i48 ON positions_memory(c4, c8) USING HASH; CREATE INDEX i49 ON positions_memory(c4, c9) USING HASH;
CREATE INDEX i56 ON positions_memory(c5, c6) USING HASH; CREATE INDEX i57 ON positions_memory(c5, c7) USING HASH;
CREATE INDEX i58 ON positions_memory(c5, c8) USING HASH; CREATE INDEX i59 ON positions_memory(c5, c9) USING HASH;
CREATE INDEX i67 ON positions_memory(c6, c7) USING HASH; CREATE INDEX i68 ON positions_memory(c6, c8) USING HASH;
CREATE INDEX i69 ON positions_memory(c6, c9) USING HASH; CREATE INDEX i78 ON positions_memory(c7, c8) USING HASH;
CREATE INDEX i79 ON positions_memory(c7, c9) USING HASH; CREATE INDEX i89 ON positions_memory(c8, c9) USING HASH;
CREATE INDEX i9 ON positions_memory(c9) USING HASH;
```

Maintenant, il s’agit de recréer les trois mêmes vues que nous avons créées pour le type de table MYISAM mais pour notre nouvelle table.

En premier lieu, la vue sur les rangées.

```USE sudoku;

DROP VIEW IF EXISTS sudoku_memory_rows_view;
CREATE VIEW sudoku_memory_rows_view AS
SELECT
r1.c1 as r1c1, r1.c2 as r1c2, r1.c3 as r1c3, r1.c4 as r1c4, r1.c5 as r1c5, r1.c6 as r1c6, r1.c7 as r1c7, r1.c8 as r1c8, r1.c9 as r1c9, r2.c1 as r2c1,
r2.c2 as r2c2, r2.c3 as r2c3, r2.c4 as r2c4, r2.c5 as r2c5, r2.c6 as r2c6, r2.c7 as r2c7, r2.c8 as r2c8, r2.c9 as r2c9, r3.c1 as r3c1, r3.c2 as r3c2,
r3.c3 as r3c3, r3.c4 as r3c4, r3.c5 as r3c5, r3.c6 as r3c6, r3.c7 as r3c7, r3.c8 as r3c8, r3.c9 as r3c9, r4.c1 as r4c1, r4.c2 as r4c2, r4.c3 as r4c3,
r4.c4 as r4c4, r4.c5 as r4c5, r4.c6 as r4c6, r4.c7 as r4c7, r4.c8 as r4c8, r4.c9 as r4c9, r5.c1 as r5c1, r5.c2 as r5c2, r5.c3 as r5c3, r5.c4 as r5c4,
r5.c5 as r5c5, r5.c6 as r5c6, r5.c7 as r5c7, r5.c8 as r5c8, r5.c9 as r5c9, r6.c1 as r6c1, r6.c2 as r6c2, r6.c3 as r6c3, r6.c4 as r6c4, r6.c5 as r6c5,
r6.c6 as r6c6, r6.c7 as r6c7, r6.c8 as r6c8, r6.c9 as r6c9, r7.c1 as r7c1, r7.c2 as r7c2, r7.c3 as r7c3, r7.c4 as r7c4, r7.c5 as r7c5, r7.c6 as r7c6,
r7.c7 as r7c7, r7.c8 as r7c8, r7.c9 as r7c9, r8.c1 as r8c1, r8.c2 as r8c2, r8.c3 as r8c3, r8.c4 as r8c4, r8.c5 as r8c5, r8.c6 as r8c6, r8.c7 as r8c7,
r8.c8 as r8c8, r8.c9 as r8c9, r9.c1 as r9c1, r9.c2 as r9c2, r9.c3 as r9c3, r9.c4 as r9c4, r9.c5 as r9c5, r9.c6 as r9c6, r9.c7 as r9c7, r9.c8 as r9c8,
r9.c9 as r9c9

FROM
positions_memory r1, positions_memory r2, positions_memory r3,
positions_memory r4, positions_memory r5, positions_memory r6,
positions_memory r7, positions_memory r8, positions_memory r9

WHERE
-- Nombres uniques dans chaque colonne
(r1.c1 <> r2.c1) AND (r1.c1 <> r3.c1) AND (r1.c1 <> r4.c1) AND (r1.c1 <> r5.c1) AND (r1.c1 <> r6.c1) AND (r1.c1 <> r7.c1) AND (r1.c1 <> r8.c1) AND (r1.c1 <> r9.c1) AND (r1.c2 <> r2.c2) AND (r1.c2 <> r3.c2) AND (r1.c2 <> r4.c2) AND (r1.c2 <> r5.c2) AND (r1.c2 <> r6.c2) AND (r1.c2 <> r7.c2) AND (r1.c2 <> r8.c2) AND (r1.c2 <> r9.c2) AND
(r1.c3 <> r2.c3) AND (r1.c3 <> r3.c3) AND (r1.c3 <> r4.c3) AND (r1.c3 <> r5.c3) AND (r1.c3 <> r6.c3) AND (r1.c3 <> r7.c3) AND (r1.c3 <> r8.c3) AND (r1.c3 <> r9.c3) AND (r1.c4 <> r2.c4) AND (r1.c4 <> r3.c4) AND (r1.c4 <> r4.c4) AND (r1.c4 <> r5.c4) AND (r1.c4 <> r6.c4) AND (r1.c4 <> r7.c4) AND (r1.c4 <> r8.c4) AND (r1.c4 <> r9.c4) AND
(r1.c5 <> r2.c5) AND (r1.c5 <> r3.c5) AND (r1.c5 <> r4.c5) AND (r1.c5 <> r5.c5) AND (r1.c5 <> r6.c5) AND (r1.c5 <> r7.c5) AND (r1.c5 <> r8.c5) AND (r1.c5 <> r9.c5) AND (r1.c6 <> r2.c6) AND (r1.c6 <> r3.c6) AND (r1.c6 <> r4.c6) AND (r1.c6 <> r5.c6) AND (r1.c6 <> r6.c6) AND (r1.c6 <> r7.c6) AND (r1.c6 <> r8.c6) AND (r1.c6 <> r9.c6) AND
(r1.c7 <> r2.c7) AND (r1.c7 <> r3.c7) AND (r1.c7 <> r4.c7) AND (r1.c7 <> r5.c7) AND (r1.c7 <> r6.c7) AND (r1.c7 <> r7.c7) AND (r1.c7 <> r8.c7) AND (r1.c7 <> r9.c7) AND (r1.c8 <> r2.c8) AND (r1.c8 <> r3.c8) AND (r1.c8 <> r4.c8) AND (r1.c8 <> r5.c8) AND (r1.c8 <> r6.c8) AND (r1.c8 <> r7.c8) AND (r1.c8 <> r8.c8) AND (r1.c8 <> r9.c8) AND
(r1.c9 <> r2.c9) AND (r1.c9 <> r3.c9) AND (r1.c9 <> r4.c9) AND (r1.c9 <> r5.c9) AND (r1.c9 <> r6.c9) AND (r1.c9 <> r7.c9) AND (r1.c9 <> r8.c9) AND (r1.c9 <> r9.c9) AND (r2.c1 <> r3.c1) AND (r2.c1 <> r4.c1) AND (r2.c1 <> r5.c1) AND (r2.c1 <> r6.c1) AND (r2.c1 <> r7.c1) AND (r2.c1 <> r8.c1) AND (r2.c1 <> r9.c1) AND (r2.c2 <> r3.c2) AND
(r2.c2 <> r4.c2) AND (r2.c2 <> r5.c2) AND (r2.c2 <> r6.c2) AND (r2.c2 <> r7.c2) AND (r2.c2 <> r8.c2) AND (r2.c2 <> r9.c2) AND (r2.c3 <> r3.c3) AND (r2.c3 <> r4.c3) AND (r2.c3 <> r5.c3) AND (r2.c3 <> r6.c3) AND (r2.c3 <> r7.c3) AND (r2.c3 <> r8.c3) AND (r2.c3 <> r9.c3) AND (r2.c4 <> r3.c4) AND (r2.c4 <> r4.c4) AND (r2.c4 <> r5.c4) AND
(r2.c4 <> r6.c4) AND (r2.c4 <> r7.c4) AND (r2.c4 <> r8.c4) AND (r2.c4 <> r9.c4) AND (r2.c5 <> r3.c5) AND (r2.c5 <> r4.c5) AND (r2.c5 <> r5.c5) AND (r2.c5 <> r6.c5) AND (r2.c5 <> r7.c5) AND (r2.c5 <> r8.c5) AND (r2.c5 <> r9.c5) AND (r2.c6 <> r3.c6) AND (r2.c6 <> r4.c6) AND (r2.c6 <> r5.c6) AND (r2.c6 <> r6.c6) AND (r2.c6 <> r7.c6) AND
(r2.c6 <> r8.c6) AND (r2.c6 <> r9.c6) AND (r2.c7 <> r3.c7) AND (r2.c7 <> r4.c7) AND (r2.c7 <> r5.c7) AND (r2.c7 <> r6.c7) AND (r2.c7 <> r7.c7) AND (r2.c7 <> r8.c7) AND (r2.c7 <> r9.c7) AND (r2.c8 <> r3.c8) AND (r2.c8 <> r4.c8) AND (r2.c8 <> r5.c8) AND (r2.c8 <> r6.c8) AND (r2.c8 <> r7.c8) AND (r2.c8 <> r8.c8) AND (r2.c8 <> r9.c8) AND
(r2.c9 <> r3.c9) AND (r2.c9 <> r4.c9) AND (r2.c9 <> r5.c9) AND (r2.c9 <> r6.c9) AND (r2.c9 <> r7.c9) AND (r2.c9 <> r8.c9) AND (r2.c9 <> r9.c9) AND (r3.c1 <> r4.c1) AND (r3.c1 <> r5.c1) AND (r3.c1 <> r6.c1) AND (r3.c1 <> r7.c1) AND (r3.c1 <> r8.c1) AND (r3.c1 <> r9.c1) AND (r3.c2 <> r4.c2) AND (r3.c2 <> r5.c2) AND (r3.c2 <> r6.c2) AND
(r3.c2 <> r7.c2) AND (r3.c2 <> r8.c2) AND (r3.c2 <> r9.c2) AND (r3.c3 <> r4.c3) AND (r3.c3 <> r5.c3) AND (r3.c3 <> r6.c3) AND (r3.c3 <> r7.c3) AND (r3.c3 <> r8.c3) AND (r3.c3 <> r9.c3) AND (r3.c4 <> r4.c4) AND (r3.c4 <> r5.c4) AND (r3.c4 <> r6.c4) AND (r3.c4 <> r7.c4) AND (r3.c4 <> r8.c4) AND (r3.c4 <> r9.c4) AND (r3.c5 <> r4.c5) AND
(r3.c5 <> r5.c5) AND (r3.c5 <> r6.c5) AND (r3.c5 <> r7.c5) AND (r3.c5 <> r8.c5) AND (r3.c5 <> r9.c5) AND (r3.c6 <> r4.c6) AND (r3.c6 <> r5.c6) AND (r3.c6 <> r6.c6) AND (r3.c6 <> r7.c6) AND (r3.c6 <> r8.c6) AND (r3.c6 <> r9.c6) AND (r3.c7 <> r4.c7) AND (r3.c7 <> r5.c7) AND (r3.c7 <> r6.c7) AND (r3.c7 <> r7.c7) AND (r3.c7 <> r8.c7) AND
(r3.c7 <> r9.c7) AND (r3.c8 <> r4.c8) AND (r3.c8 <> r5.c8) AND (r3.c8 <> r6.c8) AND (r3.c8 <> r7.c8) AND (r3.c8 <> r8.c8) AND (r3.c8 <> r9.c8) AND (r3.c9 <> r4.c9) AND (r3.c9 <> r5.c9) AND (r3.c9 <> r6.c9) AND (r3.c9 <> r7.c9) AND (r3.c9 <> r8.c9) AND (r3.c9 <> r9.c9) AND (r4.c1 <> r5.c1) AND (r4.c1 <> r6.c1) AND (r4.c1 <> r7.c1) AND
(r4.c1 <> r8.c1) AND (r4.c1 <> r9.c1) AND (r4.c2 <> r5.c2) AND (r4.c2 <> r6.c2) AND (r4.c2 <> r7.c2) AND (r4.c2 <> r8.c2) AND (r4.c2 <> r9.c2) AND (r4.c3 <> r5.c3) AND (r4.c3 <> r6.c3) AND (r4.c3 <> r7.c3) AND (r4.c3 <> r8.c3) AND (r4.c3 <> r9.c3) AND (r4.c4 <> r5.c4) AND (r4.c4 <> r6.c4) AND (r4.c4 <> r7.c4) AND (r4.c4 <> r8.c4) AND
(r4.c4 <> r9.c4) AND (r4.c5 <> r5.c5) AND (r4.c5 <> r6.c5) AND (r4.c5 <> r7.c5) AND (r4.c5 <> r8.c5) AND (r4.c5 <> r9.c5) AND (r4.c6 <> r5.c6) AND (r4.c6 <> r6.c6) AND (r4.c6 <> r7.c6) AND (r4.c6 <> r8.c6) AND (r4.c6 <> r9.c6) AND (r4.c7 <> r5.c7) AND (r4.c7 <> r6.c7) AND (r4.c7 <> r7.c7) AND (r4.c7 <> r8.c7) AND (r4.c7 <> r9.c7) AND
(r4.c8 <> r5.c8) AND (r4.c8 <> r6.c8) AND (r4.c8 <> r7.c8) AND (r4.c8 <> r8.c8) AND (r4.c8 <> r9.c8) AND (r4.c9 <> r5.c9) AND (r4.c9 <> r6.c9) AND (r4.c9 <> r7.c9) AND (r4.c9 <> r8.c9) AND (r4.c9 <> r9.c9) AND (r5.c1 <> r6.c1) AND (r5.c1 <> r7.c1) AND (r5.c1 <> r8.c1) AND (r5.c1 <> r9.c1) AND (r5.c2 <> r6.c2) AND (r5.c2 <> r7.c2) AND
(r5.c2 <> r8.c2) AND (r5.c2 <> r9.c2) AND (r5.c3 <> r6.c3) AND (r5.c3 <> r7.c3) AND (r5.c3 <> r8.c3) AND (r5.c3 <> r9.c3) AND (r5.c4 <> r6.c4) AND (r5.c4 <> r7.c4) AND (r5.c4 <> r8.c4) AND (r5.c4 <> r9.c4) AND (r5.c5 <> r6.c5) AND (r5.c5 <> r7.c5) AND (r5.c5 <> r8.c5) AND (r5.c5 <> r9.c5) AND (r5.c6 <> r6.c6) AND (r5.c6 <> r7.c6) AND
(r5.c6 <> r8.c6) AND (r5.c6 <> r9.c6) AND (r5.c7 <> r6.c7) AND (r5.c7 <> r7.c7) AND (r5.c7 <> r8.c7) AND (r5.c7 <> r9.c7) AND (r5.c8 <> r6.c8) AND (r5.c8 <> r7.c8) AND (r5.c8 <> r8.c8) AND (r5.c8 <> r9.c8) AND (r5.c9 <> r6.c9) AND (r5.c9 <> r7.c9) AND (r5.c9 <> r8.c9) AND (r5.c9 <> r9.c9) AND (r6.c1 <> r7.c1) AND (r6.c1 <> r8.c1) AND
(r6.c1 <> r9.c1) AND (r6.c2 <> r7.c2) AND (r6.c2 <> r8.c2) AND (r6.c2 <> r9.c2) AND (r6.c3 <> r7.c3) AND (r6.c3 <> r8.c3) AND (r6.c3 <> r9.c3) AND (r6.c4 <> r7.c4) AND (r6.c4 <> r8.c4) AND (r6.c4 <> r9.c4) AND (r6.c5 <> r7.c5) AND (r6.c5 <> r8.c5) AND (r6.c5 <> r9.c5) AND (r6.c6 <> r7.c6) AND (r6.c6 <> r8.c6) AND (r6.c6 <> r9.c6) AND
(r6.c7 <> r7.c7) AND (r6.c7 <> r8.c7) AND (r6.c7 <> r9.c7) AND (r6.c8 <> r7.c8) AND (r6.c8 <> r8.c8) AND (r6.c8 <> r9.c8) AND (r6.c9 <> r7.c9) AND (r6.c9 <> r8.c9) AND (r6.c9 <> r9.c9) AND (r7.c1 <> r8.c1) AND (r7.c1 <> r9.c1) AND (r7.c2 <> r8.c2) AND (r7.c2 <> r9.c2) AND (r7.c3 <> r8.c3) AND (r7.c3 <> r9.c3) AND (r7.c4 <> r8.c4) AND
(r7.c4 <> r9.c4) AND (r7.c5 <> r8.c5) AND (r7.c5 <> r9.c5) AND (r7.c6 <> r8.c6) AND (r7.c6 <> r9.c6) AND (r7.c7 <> r8.c7) AND (r7.c7 <> r9.c7) AND (r7.c8 <> r8.c8) AND (r7.c8 <> r9.c8) AND (r7.c9 <> r8.c9) AND (r7.c9 <> r9.c9) AND (r8.c1 <> r9.c1) AND (r8.c2 <> r9.c2) AND (r8.c3 <> r9.c3) AND (r8.c4 <> r9.c4) AND (r8.c5 <> r9.c5) AND
(r8.c6 <> r9.c6) AND (r8.c7 <> r9.c7) AND (r8.c8 <> r9.c8) AND (r8.c9 <> r9.c9) AND
-- Nombres uniques dans chaque maison de 3x3
(r1.c1 <> r2.c2) AND (r1.c1 <> r2.c3) AND (r1.c1 <> r3.c2) AND (r1.c1 <> r3.c3) AND (r1.c2 <> r2.c1) AND (r1.c2 <> r2.c3) AND (r1.c2 <> r3.c1) AND (r1.c2 <> r3.c3) AND (r1.c3 <> r2.c1) AND (r1.c3 <> r2.c2) AND (r1.c3 <> r3.c1) AND (r1.c3 <> r3.c2) AND (r1.c4 <> r2.c5) AND (r1.c4 <> r2.c6) AND (r1.c4 <> r3.c5) AND (r1.c4 <> r3.c6) AND
(r1.c5 <> r2.c4) AND (r1.c5 <> r2.c6) AND (r1.c5 <> r3.c4) AND (r1.c5 <> r3.c6) AND (r1.c6 <> r2.c4) AND (r1.c6 <> r2.c5) AND (r1.c6 <> r3.c4) AND (r1.c6 <> r3.c5) AND (r1.c7 <> r2.c8) AND (r1.c7 <> r2.c9) AND (r1.c7 <> r3.c8) AND (r1.c7 <> r3.c9) AND (r1.c8 <> r2.c7) AND (r1.c8 <> r2.c9) AND (r1.c8 <> r3.c7) AND (r1.c8 <> r3.c9) AND
(r1.c9 <> r2.c7) AND (r1.c9 <> r2.c8) AND (r1.c9 <> r3.c7) AND (r1.c9 <> r3.c8) AND (r2.c1 <> r3.c2) AND (r2.c1 <> r3.c3) AND (r2.c2 <> r3.c1) AND (r2.c2 <> r3.c3) AND (r2.c3 <> r3.c1) AND (r2.c3 <> r3.c2) AND (r2.c4 <> r3.c5) AND (r2.c4 <> r3.c6) AND (r2.c5 <> r3.c4) AND (r2.c5 <> r3.c6) AND (r2.c6 <> r3.c4) AND (r2.c6 <> r3.c5) AND
(r2.c7 <> r3.c8) AND (r2.c7 <> r3.c9) AND (r2.c8 <> r3.c7) AND (r2.c8 <> r3.c9) AND (r2.c9 <> r3.c7) AND (r2.c9 <> r3.c8) AND (r4.c1 <> r5.c2) AND (r4.c1 <> r5.c3) AND (r4.c1 <> r6.c2) AND (r4.c1 <> r6.c3) AND (r4.c2 <> r5.c1) AND (r4.c2 <> r5.c3) AND (r4.c2 <> r6.c1) AND (r4.c2 <> r6.c3) AND (r4.c3 <> r5.c1) AND (r4.c3 <> r5.c2) AND
(r4.c3 <> r6.c1) AND (r4.c3 <> r6.c2) AND (r4.c4 <> r5.c5) AND (r4.c4 <> r5.c6) AND (r4.c4 <> r6.c5) AND (r4.c4 <> r6.c6) AND (r4.c5 <> r5.c4) AND (r4.c5 <> r5.c6) AND (r4.c5 <> r6.c4) AND (r4.c5 <> r6.c6) AND (r4.c6 <> r5.c4) AND (r4.c6 <> r5.c5) AND (r4.c6 <> r6.c4) AND (r4.c6 <> r6.c5) AND (r4.c7 <> r5.c8) AND (r4.c7 <> r5.c9) AND
(r4.c7 <> r6.c8) AND (r4.c7 <> r6.c9) AND (r4.c8 <> r5.c7) AND (r4.c8 <> r5.c9) AND (r4.c8 <> r6.c7) AND (r4.c8 <> r6.c9) AND (r4.c9 <> r5.c7) AND (r4.c9 <> r5.c8) AND (r4.c9 <> r6.c7) AND (r4.c9 <> r6.c8) AND (r5.c1 <> r6.c2) AND (r5.c1 <> r6.c3) AND (r5.c2 <> r6.c1) AND (r5.c2 <> r6.c3) AND (r5.c3 <> r6.c1) AND (r5.c3 <> r6.c2) AND
(r5.c4 <> r6.c5) AND (r5.c4 <> r6.c6) AND (r5.c5 <> r6.c4) AND (r5.c5 <> r6.c6) AND (r5.c6 <> r6.c4) AND (r5.c6 <> r6.c5) AND (r5.c7 <> r6.c8) AND (r5.c7 <> r6.c9) AND (r5.c8 <> r6.c7) AND (r5.c8 <> r6.c9) AND (r5.c9 <> r6.c7) AND (r5.c9 <> r6.c8) AND (r7.c1 <> r8.c2) AND (r7.c1 <> r8.c3) AND (r7.c1 <> r9.c2) AND (r7.c1 <> r9.c3) AND
(r7.c2 <> r8.c1) AND (r7.c2 <> r8.c3) AND (r7.c2 <> r9.c1) AND (r7.c2 <> r9.c3) AND (r7.c3 <> r8.c1) AND (r7.c3 <> r8.c2) AND (r7.c3 <> r9.c1) AND (r7.c3 <> r9.c2) AND (r7.c4 <> r8.c5) AND (r7.c4 <> r8.c6) AND (r7.c4 <> r9.c5) AND (r7.c4 <> r9.c6) AND (r7.c5 <> r8.c4) AND (r7.c5 <> r8.c6) AND (r7.c5 <> r9.c4) AND (r7.c5 <> r9.c6) AND
(r7.c6 <> r8.c4) AND (r7.c6 <> r8.c5) AND (r7.c6 <> r9.c4) AND (r7.c6 <> r9.c5) AND (r7.c7 <> r8.c8) AND (r7.c7 <> r8.c9) AND (r7.c7 <> r9.c8) AND (r7.c7 <> r9.c9) AND (r7.c8 <> r8.c7) AND (r7.c8 <> r8.c9) AND (r7.c8 <> r9.c7) AND (r7.c8 <> r9.c9) AND (r7.c9 <> r8.c7) AND (r7.c9 <> r8.c8) AND (r7.c9 <> r9.c7) AND (r7.c9 <> r9.c8) AND
(r8.c1 <> r9.c2) AND (r8.c1 <> r9.c3) AND (r8.c2 <> r9.c1) AND (r8.c2 <> r9.c3) AND (r8.c3 <> r9.c1) AND (r8.c3 <> r9.c2) AND (r8.c4 <> r9.c5) AND (r8.c4 <> r9.c6) AND (r8.c5 <> r9.c4) AND (r8.c5 <> r9.c6) AND (r8.c6 <> r9.c4) AND (r8.c6 <> r9.c5) AND (r8.c7 <> r9.c8) AND (r8.c7 <> r9.c9) AND (r8.c8 <> r9.c7) AND (r8.c8 <> r9.c9) AND
(r8.c9 <> r9.c7) AND (r8.c9 <> r9.c8);
```

En second lieu, la vue sur les colonnes.

```USE sudoku;

DROP VIEW IF EXISTS sudoku_memory_columns_view;
CREATE VIEW sudoku_memory_columns_view AS
SELECT
col1.c1 as r1c1, col1.c2 as r2c1, col1.c3 as r3c1, col1.c4 as r4c1, col1.c5 as r5c1,col1.c6 as r6c1, col1.c7 as r7c1, col1.c8 as r8c1, col1.c9 as r9c1, col2.c1 as r1c2,
col2.c2 as r2c2, col2.c3 as r3c2, col2.c4 as r4c2, col2.c5 as r5c2, col2.c6 as r6c2,col2.c7 as r7c2, col2.c8 as r8c2, col2.c9 as r9c2, col3.c1 as r1c3, col3.c2 as r2c3,
col3.c3 as r3c3, col3.c4 as r4c3, col3.c5 as r5c3, col3.c6 as r6c3, col3.c7 as r7c3,col3.c8 as r8c3, col3.c9 as r9c3, col4.c1 as r1c4, col4.c2 as r2c4, col4.c3 as r3c4,
col4.c4 as r4c4, col4.c5 as r5c4, col4.c6 as r6c4, col4.c7 as r7c4, col4.c8 as r8c4,col4.c9 as r9c4, col5.c1 as r1c5, col5.c2 as r2c5, col5.c3 as r3c5, col5.c4 as r4c5,
col5.c5 as r5c5, col5.c6 as r6c5, col5.c7 as r7c5, col5.c8 as r8c5, col5.c9 as r9c5,col6.c1 as r1c6, col6.c2 as r2c6, col6.c3 as r3c6, col6.c4 as r4c6, col6.c5 as r5c6,
col6.c6 as r6c6, col6.c7 as r7c6, col6.c8 as r8c6, col6.c9 as r9c6, col7.c1 as r1c7,col7.c2 as r2c7, col7.c3 as r3c7, col7.c4 as r4c7, col7.c5 as r5c7, col7.c6 as r6c7,
col7.c7 as r7c7, col7.c8 as r8c7, col7.c9 as r9c7, col8.c1 as r1c8, col8.c2 as r2c8,col8.c3 as r3c8, col8.c4 as r4c8, col8.c5 as r5c8, col8.c6 as r6c8, col8.c7 as r7c8,
col8.c8 as r8c8, col8.c9 as r9c8, col9.c1 as r1c9, col9.c2 as r2c9, col9.c3 as r3c9,col9.c4 as r4c9, col9.c5 as r5c9, col9.c6 as r6c9, col9.c7 as r7c9, col9.c8 as r8c9,
col9.c9 as r9c9
FROM
positions_memory col1, positions_memory col2, positions_memory col3, positions_memory col4,
positions_memory col5, positions_memory col6, positions_memory col7, positions_memory col8, positions_memory col9
WHERE
-- Nombres uniques dans chaque rangee
(col1.c1 <> col2.c1) AND (col1.c1 <> col3.c1) AND (col1.c1 <> col4.c1) AND (col1.c1 <> col5.c1) AND (col1.c1 <> col6.c1) AND (col1.c1 <> col7.c1) AND (col1.c1 <> col8.c1) AND (col1.c1 <> col9.c1) AND (col1.c2 <> col2.c2) AND (col1.c2 <> col3.c2) AND (col1.c2 <> col4.c2) AND (col1.c2 <> col5.c2) AND (col1.c2 <> col6.c2) AND (col1.c2 <> col7.c2) AND (col1.c2 <> col8.c2) AND (col1.c2 <> col9.c2) AND (col1.c3 <> col2.c3) AND (col1.c3 <> col3.c3) AND (col1.c3 <> col4.c3) AND (col1.c3 <> col5.c3) AND (col1.c3 <> col6.c3) AND (col1.c3 <> col7.c3) AND (col1.c3 <> col8.c3) AND (col1.c3 <> col9.c3) AND (col1.c4 <> col2.c4) AND (col1.c4 <> col3.c4) AND (col1.c4 <> col4.c4) AND (col1.c4 <> col5.c4) AND (col1.c4 <> col6.c4) AND (col1.c4 <> col7.c4) AND (col1.c4 <> col8.c4) AND (col1.c4 <> col9.c4) AND
(col1.c5 <> col2.c5) AND (col1.c5 <> col3.c5) AND (col1.c5 <> col4.c5) AND (col1.c5 <> col5.c5) AND (col1.c5 <> col6.c5) AND (col1.c5 <> col7.c5) AND (col1.c5 <> col8.c5) AND (col1.c5 <> col9.c5) AND (col1.c6 <> col2.c6) AND (col1.c6 <> col3.c6) AND (col1.c6 <> col4.c6) AND (col1.c6 <> col5.c6) AND (col1.c6 <> col6.c6) AND (col1.c6 <> col7.c6) AND (col1.c6 <> col8.c6) AND (col1.c6 <> col9.c6) AND (col1.c7 <> col2.c7) AND (col1.c7 <> col3.c7) AND (col1.c7 <> col4.c7) AND (col1.c7 <> col5.c7) AND (col1.c7 <> col6.c7) AND (col1.c7 <> col7.c7) AND (col1.c7 <> col8.c7) AND (col1.c7 <> col9.c7) AND (col1.c8 <> col2.c8) AND (col1.c8 <> col3.c8) AND (col1.c8 <> col4.c8) AND (col1.c8 <> col5.c8) AND (col1.c8 <> col6.c8) AND (col1.c8 <> col7.c8) AND (col1.c8 <> col8.c8) AND (col1.c8 <> col9.c8) AND
(col1.c9 <> col2.c9) AND (col1.c9 <> col3.c9) AND (col1.c9 <> col4.c9) AND (col1.c9 <> col5.c9) AND (col1.c9 <> col6.c9) AND (col1.c9 <> col7.c9) AND (col1.c9 <> col8.c9) AND (col1.c9 <> col9.c9) AND (col2.c1 <> col3.c1) AND (col2.c1 <> col4.c1) AND (col2.c1 <> col5.c1) AND (col2.c1 <> col6.c1) AND (col2.c1 <> col7.c1) AND (col2.c1 <> col8.c1) AND (col2.c1 <> col9.c1) AND (col2.c2 <> col3.c2) AND (col2.c2 <> col4.c2) AND (col2.c2 <> col5.c2) AND (col2.c2 <> col6.c2) AND (col2.c2 <> col7.c2) AND (col2.c2 <> col8.c2) AND (col2.c2 <> col9.c2) AND (col2.c3 <> col3.c3) AND (col2.c3 <> col4.c3) AND (col2.c3 <> col5.c3) AND (col2.c3 <> col6.c3) AND (col2.c3 <> col7.c3) AND (col2.c3 <> col8.c3) AND (col2.c3 <> col9.c3) AND (col2.c4 <> col3.c4) AND (col2.c4 <> col4.c4) AND (col2.c4 <> col5.c4) AND
(col2.c4 <> col6.c4) AND (col2.c4 <> col7.c4) AND (col2.c4 <> col8.c4) AND (col2.c4 <> col9.c4) AND (col2.c5 <> col3.c5) AND (col2.c5 <> col4.c5) AND (col2.c5 <> col5.c5) AND (col2.c5 <> col6.c5) AND (col2.c5 <> col7.c5) AND (col2.c5 <> col8.c5) AND (col2.c5 <> col9.c5) AND (col2.c6 <> col3.c6) AND (col2.c6 <> col4.c6) AND (col2.c6 <> col5.c6) AND (col2.c6 <> col6.c6) AND (col2.c6 <> col7.c6) AND (col2.c6 <> col8.c6) AND (col2.c6 <> col9.c6) AND (col2.c7 <> col3.c7) AND (col2.c7 <> col4.c7) AND (col2.c7 <> col5.c7) AND (col2.c7 <> col6.c7) AND (col2.c7 <> col7.c7) AND (col2.c7 <> col8.c7) AND (col2.c7 <> col9.c7) AND (col2.c8 <> col3.c8) AND (col2.c8 <> col4.c8) AND (col2.c8 <> col5.c8) AND (col2.c8 <> col6.c8) AND (col2.c8 <> col7.c8) AND (col2.c8 <> col8.c8) AND (col2.c8 <> col9.c8) AND
(col2.c9 <> col3.c9) AND (col2.c9 <> col4.c9) AND (col2.c9 <> col5.c9) AND (col2.c9 <> col6.c9) AND (col2.c9 <> col7.c9) AND (col2.c9 <> col8.c9) AND (col2.c9 <> col9.c9) AND (col3.c1 <> col4.c1) AND (col3.c1 <> col5.c1) AND (col3.c1 <> col6.c1) AND (col3.c1 <> col7.c1) AND (col3.c1 <> col8.c1) AND (col3.c1 <> col9.c1) AND (col3.c2 <> col4.c2) AND (col3.c2 <> col5.c2) AND (col3.c2 <> col6.c2) AND (col3.c2 <> col7.c2) AND (col3.c2 <> col8.c2) AND (col3.c2 <> col9.c2) AND (col3.c3 <> col4.c3) AND (col3.c3 <> col5.c3) AND (col3.c3 <> col6.c3) AND (col3.c3 <> col7.c3) AND (col3.c3 <> col8.c3) AND (col3.c3 <> col9.c3) AND (col3.c4 <> col4.c4) AND (col3.c4 <> col5.c4) AND (col3.c4 <> col6.c4) AND (col3.c4 <> col7.c4) AND (col3.c4 <> col8.c4) AND (col3.c4 <> col9.c4) AND (col3.c5 <> col4.c5) AND
(col3.c5 <> col5.c5) AND (col3.c5 <> col6.c5) AND (col3.c5 <> col7.c5) AND (col3.c5 <> col8.c5) AND (col3.c5 <> col9.c5) AND (col3.c6 <> col4.c6) AND (col3.c6 <> col5.c6) AND (col3.c6 <> col6.c6) AND (col3.c6 <> col7.c6) AND (col3.c6 <> col8.c6) AND (col3.c6 <> col9.c6) AND (col3.c7 <> col4.c7) AND (col3.c7 <> col5.c7) AND (col3.c7 <> col6.c7) AND (col3.c7 <> col7.c7) AND (col3.c7 <> col8.c7) AND (col3.c7 <> col9.c7) AND (col3.c8 <> col4.c8) AND (col3.c8 <> col5.c8) AND (col3.c8 <> col6.c8) AND (col3.c8 <> col7.c8) AND (col3.c8 <> col8.c8) AND (col3.c8 <> col9.c8) AND (col3.c9 <> col4.c9) AND (col3.c9 <> col5.c9) AND (col3.c9 <> col6.c9) AND (col3.c9 <> col7.c9) AND (col3.c9 <> col8.c9) AND (col3.c9 <> col9.c9) AND (col4.c1 <> col5.c1) AND (col4.c1 <> col6.c1) AND (col4.c1 <> col7.c1) AND
(col4.c1 <> col8.c1) AND (col4.c1 <> col9.c1) AND (col4.c2 <> col5.c2) AND (col4.c2 <> col6.c2) AND (col4.c2 <> col7.c2) AND (col4.c2 <> col8.c2) AND (col4.c2 <> col9.c2) AND (col4.c3 <> col5.c3) AND (col4.c3 <> col6.c3) AND (col4.c3 <> col7.c3) AND (col4.c3 <> col8.c3) AND (col4.c3 <> col9.c3) AND (col4.c4 <> col5.c4) AND (col4.c4 <> col6.c4) AND (col4.c4 <> col7.c4) AND (col4.c4 <> col8.c4) AND (col4.c4 <> col9.c4) AND (col4.c5 <> col5.c5) AND (col4.c5 <> col6.c5) AND (col4.c5 <> col7.c5) AND (col4.c5 <> col8.c5) AND (col4.c5 <> col9.c5) AND (col4.c6 <> col5.c6) AND (col4.c6 <> col6.c6) AND (col4.c6 <> col7.c6) AND (col4.c6 <> col8.c6) AND (col4.c6 <> col9.c6) AND (col4.c7 <> col5.c7) AND (col4.c7 <> col6.c7) AND (col4.c7 <> col7.c7) AND (col4.c7 <> col8.c7) AND (col4.c7 <> col9.c7) AND
(col4.c8 <> col5.c8) AND (col4.c8 <> col6.c8) AND (col4.c8 <> col7.c8) AND (col4.c8 <> col8.c8) AND (col4.c8 <> col9.c8) AND (col4.c9 <> col5.c9) AND (col4.c9 <> col6.c9) AND (col4.c9 <> col7.c9) AND (col4.c9 <> col8.c9) AND (col4.c9 <> col9.c9) AND (col5.c1 <> col6.c1) AND (col5.c1 <> col7.c1) AND (col5.c1 <> col8.c1) AND (col5.c1 <> col9.c1) AND (col5.c2 <> col6.c2) AND (col5.c2 <> col7.c2) AND (col5.c2 <> col8.c2) AND (col5.c2 <> col9.c2) AND (col5.c3 <> col6.c3) AND (col5.c3 <> col7.c3) AND (col5.c3 <> col8.c3) AND (col5.c3 <> col9.c3) AND (col5.c4 <> col6.c4) AND (col5.c4 <> col7.c4) AND (col5.c4 <> col8.c4) AND (col5.c4 <> col9.c4) AND (col5.c5 <> col6.c5) AND (col5.c5 <> col7.c5) AND (col5.c5 <> col8.c5) AND (col5.c5 <> col9.c5) AND (col5.c6 <> col6.c6) AND (col5.c6 <> col7.c6) AND
(col5.c6 <> col8.c6) AND (col5.c6 <> col9.c6) AND (col5.c7 <> col6.c7) AND (col5.c7 <> col7.c7) AND (col5.c7 <> col8.c7) AND (col5.c7 <> col9.c7) AND (col5.c8 <> col6.c8) AND (col5.c8 <> col7.c8) AND (col5.c8 <> col8.c8) AND (col5.c8 <> col9.c8) AND (col5.c9 <> col6.c9) AND (col5.c9 <> col7.c9) AND (col5.c9 <> col8.c9) AND (col5.c9 <> col9.c9) AND (col6.c1 <> col7.c1) AND (col6.c1 <> col8.c1) AND (col6.c1 <> col9.c1) AND (col6.c2 <> col7.c2) AND (col6.c2 <> col8.c2) AND (col6.c2 <> col9.c2) AND (col6.c3 <> col7.c3) AND (col6.c3 <> col8.c3) AND (col6.c3 <> col9.c3) AND (col6.c4 <> col7.c4) AND (col6.c4 <> col8.c4) AND (col6.c4 <> col9.c4) AND (col6.c5 <> col7.c5) AND (col6.c5 <> col8.c5) AND (col6.c5 <> col9.c5) AND (col6.c6 <> col7.c6) AND (col6.c6 <> col8.c6) AND (col6.c6 <> col9.c6) AND
(col6.c7 <> col7.c7) AND (col6.c7 <> col8.c7) AND (col6.c7 <> col9.c7) AND (col6.c8 <> col7.c8) AND (col6.c8 <> col8.c8) AND (col6.c8 <> col9.c8) AND (col6.c9 <> col7.c9) AND (col6.c9 <> col8.c9) AND (col6.c9 <> col9.c9) AND (col7.c1 <> col8.c1) AND (col7.c1 <> col9.c1) AND (col7.c2 <> col8.c2) AND (col7.c2 <> col9.c2) AND (col7.c3 <> col8.c3) AND (col7.c3 <> col9.c3) AND (col7.c4 <> col8.c4) AND (col7.c4 <> col9.c4) AND (col7.c5 <> col8.c5) AND (col7.c5 <> col9.c5) AND (col7.c6 <> col8.c6) AND (col7.c6 <> col9.c6) AND (col7.c7 <> col8.c7) AND (col7.c7 <> col9.c7) AND (col7.c8 <> col8.c8) AND (col7.c8 <> col9.c8) AND (col7.c9 <> col8.c9) AND (col7.c9 <> col9.c9) AND (col8.c1 <> col9.c1) AND (col8.c2 <> col9.c2) AND (col8.c3 <> col9.c3) AND (col8.c4 <> col9.c4) AND (col8.c5 <> col9.c5) AND
(col8.c6 <> col9.c6) AND (col8.c7 <> col9.c7) AND (col8.c8 <> col9.c8) AND (col8.c9 <> col9.c9) AND
-- Nombres uniques dans chaque maison de 3x3
(col1.c1 <> col1.c2) AND (col1.c1 <> col1.c3) AND (col1.c1 <> col2.c2) AND (col1.c1 <> col2.c3) AND (col1.c1 <> col3.c2) AND (col1.c1 <> col3.c3) AND (col1.c2 <> col1.c3) AND (col1.c2 <> col2.c1) AND (col1.c2 <> col2.c3) AND (col1.c2 <> col3.c1) AND (col1.c2 <> col3.c3) AND (col1.c3 <> col2.c1) AND (col1.c3 <> col2.c2) AND (col1.c3 <> col3.c1) AND (col1.c3 <> col3.c2) AND (col1.c4 <> col1.c5) AND (col1.c4 <> col1.c6) AND (col1.c4 <> col2.c5) AND (col1.c4 <> col2.c6) AND (col1.c4 <> col3.c5) AND (col1.c4 <> col3.c6) AND (col1.c5 <> col1.c6) AND (col1.c5 <> col2.c4) AND (col1.c5 <> col2.c6) AND (col1.c5 <> col3.c4) AND (col1.c5 <> col3.c6) AND (col1.c6 <> col2.c4) AND (col1.c6 <> col2.c5) AND (col1.c6 <> col3.c4) AND (col1.c6 <> col3.c5) AND (col1.c7 <> col1.c8) AND (col1.c7 <> col1.c9) AND
(col1.c7 <> col2.c8) AND (col1.c7 <> col2.c9) AND (col1.c7 <> col3.c8) AND (col1.c7 <> col3.c9) AND (col1.c8 <> col1.c9) AND (col1.c8 <> col2.c7) AND (col1.c8 <> col2.c9) AND (col1.c8 <> col3.c7) AND (col1.c8 <> col3.c9) AND (col1.c9 <> col2.c7) AND (col1.c9 <> col2.c8) AND (col1.c9 <> col3.c7) AND (col1.c9 <> col3.c8) AND (col2.c1 <> col2.c2) AND (col2.c1 <> col2.c3) AND (col2.c1 <> col3.c2) AND (col2.c1 <> col3.c3) AND (col2.c2 <> col2.c3) AND (col2.c2 <> col3.c1) AND (col2.c2 <> col3.c3) AND (col2.c3 <> col3.c1) AND (col2.c3 <> col3.c2) AND (col2.c4 <> col2.c5) AND (col2.c4 <> col2.c6) AND (col2.c4 <> col3.c5) AND (col2.c4 <> col3.c6) AND (col2.c5 <> col2.c6) AND (col2.c5 <> col3.c4) AND (col2.c5 <> col3.c6) AND (col2.c6 <> col3.c4) AND (col2.c6 <> col3.c5) AND (col2.c7 <> col2.c8) AND
(col2.c7 <> col2.c9) AND (col2.c7 <> col3.c8) AND (col2.c7 <> col3.c9) AND (col2.c8 <> col2.c9) AND (col2.c8 <> col3.c7) AND (col2.c8 <> col3.c9) AND (col2.c9 <> col3.c7) AND (col2.c9 <> col3.c8) AND (col3.c1 <> col3.c2) AND (col3.c1 <> col3.c3) AND (col3.c2 <> col3.c3) AND (col3.c4 <> col3.c5) AND (col3.c4 <> col3.c6) AND (col3.c5 <> col3.c6) AND (col3.c7 <> col3.c8) AND (col3.c7 <> col3.c9) AND (col3.c8 <> col3.c9) AND (col4.c1 <> col4.c2) AND (col4.c1 <> col4.c3) AND (col4.c1 <> col5.c2) AND (col4.c1 <> col5.c3) AND (col4.c1 <> col6.c2) AND (col4.c1 <> col6.c3) AND (col4.c2 <> col4.c3) AND (col4.c2 <> col5.c1) AND (col4.c2 <> col5.c3) AND (col4.c2 <> col6.c1) AND (col4.c2 <> col6.c3) AND (col4.c3 <> col5.c1) AND (col4.c3 <> col5.c2) AND (col4.c3 <> col6.c1) AND (col4.c3 <> col6.c2) AND
(col4.c4 <> col4.c5) AND (col4.c4 <> col4.c6) AND (col4.c4 <> col5.c5) AND (col4.c4 <> col5.c6) AND (col4.c4 <> col6.c5) AND (col4.c4 <> col6.c6) AND (col4.c5 <> col4.c6) AND (col4.c5 <> col5.c4) AND (col4.c5 <> col5.c6) AND (col4.c5 <> col6.c4) AND (col4.c5 <> col6.c6) AND (col4.c6 <> col5.c4) AND (col4.c6 <> col5.c5) AND (col4.c6 <> col6.c4) AND (col4.c6 <> col6.c5) AND (col4.c7 <> col4.c8) AND (col4.c7 <> col4.c9) AND (col4.c7 <> col5.c8) AND (col4.c7 <> col5.c9) AND (col4.c7 <> col6.c8) AND (col4.c7 <> col6.c9) AND (col4.c8 <> col4.c9) AND (col4.c8 <> col5.c7) AND (col4.c8 <> col5.c9) AND (col4.c8 <> col6.c7) AND (col4.c8 <> col6.c9) AND (col4.c9 <> col5.c7) AND (col4.c9 <> col5.c8) AND (col4.c9 <> col6.c7) AND (col4.c9 <> col6.c8) AND (col5.c1 <> col5.c2) AND (col5.c1 <> col5.c3) AND
(col5.c1 <> col6.c2) AND (col5.c1 <> col6.c3) AND (col5.c2 <> col5.c3) AND (col5.c2 <> col6.c1) AND (col5.c2 <> col6.c3) AND (col5.c3 <> col6.c1) AND (col5.c3 <> col6.c2) AND (col5.c4 <> col5.c5) AND (col5.c4 <> col5.c6) AND (col5.c4 <> col6.c5) AND (col5.c4 <> col6.c6) AND (col5.c5 <> col5.c6) AND (col5.c5 <> col6.c4) AND (col5.c5 <> col6.c6) AND (col5.c6 <> col6.c4) AND (col5.c6 <> col6.c5) AND (col5.c7 <> col5.c8) AND (col5.c7 <> col5.c9) AND (col5.c7 <> col6.c8) AND (col5.c7 <> col6.c9) AND (col5.c8 <> col5.c9) AND (col5.c8 <> col6.c7) AND (col5.c8 <> col6.c9) AND (col5.c9 <> col6.c7) AND (col5.c9 <> col6.c8) AND (col6.c1 <> col6.c2) AND (col6.c1 <> col6.c3) AND (col6.c2 <> col6.c3) AND (col6.c4 <> col6.c5) AND (col6.c4 <> col6.c6) AND (col6.c5 <> col6.c6) AND (col6.c7 <> col6.c8) AND
(col6.c7 <> col6.c9) AND (col6.c8 <> col6.c9) AND (col7.c1 <> col7.c2) AND (col7.c1 <> col7.c3) AND (col7.c1 <> col8.c2) AND (col7.c1 <> col8.c3) AND (col7.c1 <> col9.c2) AND (col7.c1 <> col9.c3) AND (col7.c2 <> col7.c3) AND (col7.c2 <> col8.c1) AND (col7.c2 <> col8.c3) AND (col7.c2 <> col9.c1) AND (col7.c2 <> col9.c3) AND (col7.c3 <> col8.c1) AND (col7.c3 <> col8.c2) AND (col7.c3 <> col9.c1) AND (col7.c3 <> col9.c2) AND (col7.c4 <> col7.c5) AND (col7.c4 <> col7.c6) AND (col7.c4 <> col8.c5) AND (col7.c4 <> col8.c6) AND (col7.c4 <> col9.c5) AND (col7.c4 <> col9.c6) AND (col7.c5 <> col7.c6) AND (col7.c5 <> col8.c4) AND (col7.c5 <> col8.c6) AND (col7.c5 <> col9.c4) AND (col7.c5 <> col9.c6) AND (col7.c6 <> col8.c4) AND (col7.c6 <> col8.c5) AND (col7.c6 <> col9.c4) AND (col7.c6 <> col9.c5) AND
(col7.c7 <> col7.c8) AND (col7.c7 <> col7.c9) AND (col7.c7 <> col8.c8) AND (col7.c7 <> col8.c9) AND (col7.c7 <> col9.c8) AND (col7.c7 <> col9.c9) AND (col7.c8 <> col7.c9) AND (col7.c8 <> col8.c7) AND (col7.c8 <> col8.c9) AND (col7.c8 <> col9.c7) AND (col7.c8 <> col9.c9) AND (col7.c9 <> col8.c7) AND (col7.c9 <> col8.c8) AND (col7.c9 <> col9.c7) AND (col7.c9 <> col9.c8) AND (col8.c1 <> col8.c2) AND (col8.c1 <> col8.c3) AND (col8.c1 <> col9.c2) AND (col8.c1 <> col9.c3) AND (col8.c2 <> col8.c3) AND (col8.c2 <> col9.c1) AND (col8.c2 <> col9.c3) AND (col8.c3 <> col9.c1) AND (col8.c3 <> col9.c2) AND (col8.c4 <> col8.c5) AND (col8.c4 <> col8.c6) AND (col8.c4 <> col9.c5) AND (col8.c4 <> col9.c6) AND (col8.c5 <> col8.c6) AND (col8.c5 <> col9.c4) AND (col8.c5 <> col9.c6) AND (col8.c6 <> col9.c4) AND
(col8.c6 <> col9.c5) AND (col8.c7 <> col8.c8) AND (col8.c7 <> col8.c9) AND (col8.c7 <> col9.c8) AND (col8.c7 <> col9.c9) AND (col8.c8 <> col8.c9) AND (col8.c8 <> col9.c7) AND (col8.c8 <> col9.c9) AND (col8.c9 <> col9.c7) AND (col8.c9 <> col9.c8) AND (col9.c1 <> col9.c2) AND (col9.c1 <> col9.c3) AND (col9.c2 <> col9.c3) AND (col9.c4 <> col9.c5) AND (col9.c4 <> col9.c6) AND (col9.c5 <> col9.c6) AND (col9.c7 <> col9.c8) AND (col9.c7 <> col9.c9) AND (col9.c8 <> col9.c9);
```

Finalement, la vue combinée.

```USE sudoku;

DROP VIEW IF EXISTS sudoku_memory_combined_view;
CREATE VIEW sudoku_memory_combined_view AS
SELECT t1.*
FROM sudoku_memory_rows_view t1
INNER JOIN sudoku_memory_columns_view t2
ON

-- Jointures entre représentation-colonnes et représentation-rangées
(t1.r1c1 = t2.r1c1) AND (t1.r1c2 = t2.r1c2) AND (t1.r1c3 = t2.r1c3) AND (t1.r1c4 = t2.r1c4) AND
(t1.r1c5 = t2.r1c5) AND (t1.r1c6 = t2.r1c6) AND (t1.r1c7 = t2.r1c7) AND (t1.r1c8 = t2.r1c8) AND
(t1.r1c9 = t2.r1c9) AND (t1.r2c1 = t2.r2c1) AND (t1.r2c2 = t2.r2c2) AND (t1.r2c3 = t2.r2c3) AND
(t1.r2c4 = t2.r2c4) AND (t1.r2c5 = t2.r2c5) AND (t1.r2c6 = t2.r2c6) AND (t1.r2c7 = t2.r2c7) AND
(t1.r2c8 = t2.r2c8) AND (t1.r2c9 = t2.r2c9) AND (t1.r3c1 = t2.r3c1) AND (t1.r3c2 = t2.r3c2) AND
(t1.r3c3 = t2.r3c3) AND (t1.r3c4 = t2.r3c4) AND (t1.r3c5 = t2.r3c5) AND (t1.r3c6 = t2.r3c6) AND
(t1.r3c7 = t2.r3c7) AND (t1.r3c8 = t2.r3c8) AND (t1.r3c9 = t2.r3c9) AND (t1.r4c1 = t2.r4c1) AND
(t1.r4c2 = t2.r4c2) AND (t1.r4c3 = t2.r4c3) AND (t1.r4c4 = t2.r4c4) AND (t1.r4c5 = t2.r4c5) AND
(t1.r4c6 = t2.r4c6) AND (t1.r4c7 = t2.r4c7) AND (t1.r4c8 = t2.r4c8) AND (t1.r4c9 = t2.r4c9) AND
(t1.r5c1 = t2.r5c1) AND (t1.r5c2 = t2.r5c2) AND (t1.r5c3 = t2.r5c3) AND (t1.r5c4 = t2.r5c4) AND
(t1.r5c5 = t2.r5c5) AND (t1.r5c6 = t2.r5c6) AND (t1.r5c7 = t2.r5c7) AND (t1.r5c8 = t2.r5c8) AND
(t1.r5c9 = t2.r5c9) AND (t1.r6c1 = t2.r6c1) AND (t1.r6c2 = t2.r6c2) AND (t1.r6c3 = t2.r6c3) AND
(t1.r6c4 = t2.r6c4) AND (t1.r6c5 = t2.r6c5) AND (t1.r6c6 = t2.r6c6) AND (t1.r6c7 = t2.r6c7) AND
(t1.r6c8 = t2.r6c8) AND (t1.r6c9 = t2.r6c9) AND (t1.r7c1 = t2.r7c1) AND (t1.r7c2 = t2.r7c2) AND
(t1.r7c3 = t2.r7c3) AND (t1.r7c4 = t2.r7c4) AND (t1.r7c5 = t2.r7c5) AND (t1.r7c6 = t2.r7c6) AND
(t1.r7c7 = t2.r7c7) AND (t1.r7c8 = t2.r7c8) AND (t1.r7c9 = t2.r7c9) AND (t1.r8c1 = t2.r8c1) AND
(t1.r8c2 = t2.r8c2) AND (t1.r8c3 = t2.r8c3) AND (t1.r8c4 = t2.r8c4) AND (t1.r8c5 = t2.r8c5) AND
(t1.r8c6 = t2.r8c6) AND (t1.r8c7 = t2.r8c7) AND (t1.r8c8 = t2.r8c8) AND (t1.r8c9 = t2.r8c9) AND
(t1.r9c1 = t2.r9c1) AND (t1.r9c2 = t2.r9c2) AND (t1.r9c3 = t2.r9c3) AND (t1.r9c4 = t2.r9c4) AND
(t1.r9c5 = t2.r9c5) AND (t1.r9c6 = t2.r9c6) AND (t1.r9c7 = t2.r9c7) AND (t1.r9c8 = t2.r9c8) AND
(t1.r9c9 = t2.r9c9);
```

Réessayons l’exemple du début de cet article pour comparer :

```
mysql> SELECT *
-> FROM sudoku_memory_combined_view
-> WHERE
-> (r2c2 = 3) AND (r2c3 = 4) AND (r2c4 = 8) AND (r2c5 = 2) AND
-> (r2c6 = 5) AND (r2c7 = 6) AND (r2c8 = 9) AND (r3c2 = 5) AND
-> (r3c3 = 9) AND (r3c4 = 3) AND (r3c5 = 6) AND (r3c6 = 4) AND
-> (r3c7 = 1) AND (r3c8 = 8) AND (r4c2 = 9) AND (r4c3 = 7) AND
-> (r4c4 = 1) AND (r4c5 = 8) AND (r4c6 = 2) AND (r4c7 = 5) AND
-> (r4c8 = 6) AND (r6c2 = 8) AND (r6c3 = 1) AND (r6c4 = 4) AND
-> (r6c5 = 7) AND (r6c6 = 6) AND (r6c7 = 2) AND (r6c8 = 3) AND
-> (r7c2 = 2) AND (r7c3 = 5) AND (r7c4 = 6) AND (r7c5 = 4) AND
-> (r7c6 = 1) AND (r7c7 = 9) AND (r7c8 = 7) AND (r8c2 = 7) AND
-> (r8c3 = 6) AND (r8c4 = 5) AND (r8c5 = 3) AND (r8c6 = 8) AND
-> (r8c7 = 4) AND (r8c8 = 2);
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| r1c1 | r1c2 | r1c3 | r1c4 | r1c5 | r1c6 | r1c7 | r1c8 | r1c9 | r2c1 | r2c2 | r2c3 | r2c4 | r2c5 | r2c6 | r2c7 | r2c8 | r2c9 | r3c1 | r3c2 | r3c3 | r3c4 | r3c5 | r3c6 | r3c7 | r3c8 | r3c9 | r4c1 | r4c2 | r4c3 | r4c4 | r4c5 | r4c6 | r4c7 | r4c8 | r4c9 | r5c1 | r5c2 | r5c3 | r5c4 | r5c5 | r5c6 | r5c7 | r5c8 | r5c9 | r6c1 | r6c2 | r6c3 | r6c4 | r6c5 | r6c6 | r6c7 | r6c8 | r6c9 | r7c1 | r7c2 | r7c3 | r7c4 | r7c5 | r7c6 | r7c7 | r7c8 | r7c9 | r8c1 | r8c2 | r8c3 | r8c4 | r8c5 | r8c6 | r8c7 | r8c8 | r8c9 | r9c1 | r9c2 | r9c3 | r9c4 | r9c5 | r9c6 | r9c7 | r9c8 | r9c9 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|   2  |   6  |   8  |   7  |   1  |   9  |   3  |   4  |   5  |   1  |   3  |   4  |   8  |   2  |   5  |   6  |   9  |   7  |   7  |   5  |   9  |   3  |   6  |   4  |   1  |   8  |   2  |   3  |   9  |   7  |   1  |   8  |   2  |   5  |   6  |   4  |   6  |   4  |   2  |   9  |   5  |   3  |   7  |   1  |   8  |   5  |   8  |   1  |   4  |   7  |   6  |   2  |   3  |   9  |   8  |   2  |   5  |   6  |   4  |   1  |   9  |   7  |   3  |   9  |   7  |   6  |   5  |   3  |   8  |   4  |   2  |   1  |   4  |   1  |   3  |   2  |   9  |   7  |   8  |   5  |   6  |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1 row in set (0.55 sec)

```

Wow! Nous sommes passés de 1.5 à 0.55 seconde! Maintenant, qu’en est-il de notre grille à 17 révélés ?

```mysql> SELECT *
-> FROM sudoku_memory_combined_view
-> WHERE
-> (r1c8 = 1) AND
-> (r2c1 = 4) AND
-> (r3c2 = 2) AND
-> (r4c5 = 5) AND
-> (r4c7 = 4) AND
-> (r4c9 = 7) AND
-> (r5c3 = 8) AND
-> (r5c7 = 3) AND
-> (r6c3 = 1) AND
-> (r6c5 = 9) AND
-> (r7c1 = 3) AND
-> (r7c4 = 4) AND
-> (r7c7 = 2) AND
-> (r8c2 = 5) AND
-> (r8c4 = 1) AND
-> (r9c4 = 8) AND
-> (r9c6 = 6);
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| r1c1 | r1c2 | r1c3 | r1c4 | r1c5 | r1c6 | r1c7 | r1c8 | r1c9 | r2c1 | r2c2 | r2c3 | r2c4 | r2c5 | r2c6 | r2c7 | r2c8 | r2c9 | r3c1 | r3c2 | r3c3 | r3c4 | r3c5 | r3c6 | r3c7 | r3c8 | r3c9 | r4c1 | r4c2 | r4c3 | r4c4 | r4c5 | r4c6 | r4c7 | r4c8 | r4c9 | r5c1 | r5c2 | r5c3 | r5c4 | r5c5 | r5c6 | r5c7 | r5c8 | r5c9 | r6c1 | r6c2 | r6c3 | r6c4 | r6c5 | r6c6 | r6c7 | r6c8 | r6c9 | r7c1 | r7c2 | r7c3 | r7c4 | r7c5 | r7c6 | r7c7 | r7c8 | r7c9 | r8c1 | r8c2 | r8c3 | r8c4 | r8c5 | r8c6 | r8c7 | r8c8 | r8c9 | r9c1 | r9c2 | r9c3 | r9c4 | r9c5 | r9c6 | r9c7 | r9c8 | r9c9 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|    6 |    9 |    3 |    7 |    8 |    4 |    5 |    1 |    2 |    4 |    8 |    7 |    5 |    1 |    2 |    9 |    3 |    6 |    1 |    2 |    5 |    9 |    6 |    3 |    8 |    7 |    4 |    9 |    3 |    2 |    6 |    5 |    1 |    4 |    8 |    7 |    5 |    6 |    8 |    2 |    4 |    7 |    3 |    9 |    1 |    7 |    4 |    1 |    3 |    9 |    8 |    6 |    2 |    5 |    3 |    1 |    9 |    4 |    7 |    5 |    2 |    6 |    8 |    8 |    5 |    6 |    1 |    2 |    9 |    7 |    4 |    3 |    2 |    7 |    4 |    8 |    3 |    6 |    1 |    5 |    9 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1 row in set (7.41 sec)
```

Fantastique!  Nous sommes passés de 20 minutes à 7 secondes!  Mais il y a encore place à amélioration!

5. Presser encore plus fort

Maintenant que nous sommes en mesure d’obtenir des résultats dans des temps raisonnables en utilisant une table de type MEMORY, nous pouvons regarder du côté des variables système pour essayer de les optimiser.

Mais avant de se lancer dans cette entreprise, il importe d’avoir un jeu d’essai afin d’effectuer des tests reproduisibles et mesurables pour vérifier l’impact de chacun des changements sur ces variables.

Nous allons tout d’abord créer une table qui nous permettra de sauvegarder le temps d’exécution de toutes les grilles de notre jeu d’essai.

```DROP TABLE IF EXISTS tests;

CREATE TABLE tests (
debut DATETIME,
fin DATETIME
) ENGINE=MYISAM;
```

Maintenant, nous allons créer notre jeu d’essai.  Évidemment notre échantillon de grilles est varié de façon à être représentatif afin  de mesurer chaque option de façon précise.

```USE sudoku;
TRUNCATE tests;
INSERT INTO tests(debut, fin) VALUES (NOW(), NULL);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 1) AND (r1c3 = 3) AND (r1c4 = 7) AND (r1c9 = 5) AND (r2c4 = 6) AND (r2c6 = 4) AND (r3c1 = 8) AND (r4c4 = 8) AND (r4c5 = 1) AND (r5c2 = 9) AND (r5c7 = 7) AND (r6c2 = 6) AND (r6c8 = 9) AND (r7c2 = 2) AND (r7c7 = 4) AND (r8c1 = 5) AND (r8c5 = 3) AND (r9c8 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 8) AND (r1c4 = 3) AND (r1c6 = 7) AND (r2c3 = 9) AND (r3c1 = 2) AND (r3c2 = 7) AND (r3c5 = 4) AND (r4c2 = 3) AND (r4c5 = 1) AND (r5c1 = 4) AND (r5c4 = 9) AND (r5c7 = 2) AND (r5c8 = 8) AND (r6c4 = 6) AND (r6c6 = 2) AND (r6c7 = 4) AND (r6c8 = 3) AND (r7c1 = 3) AND (r7c2 = 1) AND (r7c6 = 6) AND (r8c1 = 6) AND (r8c3 = 8) AND (r8c4 = 1) AND (r8c9 = 7) AND (r9c5 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 2) AND (r1c8 = 1) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 3) AND (r3c5 = 5) AND (r4c4 = 4) AND (r4c8 = 6) AND (r5c3 = 2) AND (r5c7 = 9) AND (r6c2 = 5) AND (r6c6 = 8) AND (r7c5 = 3) AND (r7c7 = 5) AND (r8c1 = 7) AND (r8c2 = 9) AND (r8c4 = 1) AND (r9c2 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r2c2 = 8) AND (r3c5 = 5) AND (r3c6 = 3) AND (r3c8 = 8) AND (r3c9 = 9) AND (r4c2 = 2) AND (r4c3 = 4) AND (r4c6 = 9) AND (r5c5 = 1) AND (r5c9 = 5) AND (r6c2 = 1) AND (r6c6 = 7) AND (r7c3 = 2) AND (r7c4 = 1) AND (r7c7 = 3) AND (r8c1 = 9) AND (r8c6 = 5) AND (r8c9 = 7) AND (r9c1 = 5) AND (r9c5 = 8) AND (r9c8 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 5) AND (r1c6 = 8) AND (r1c7 = 6) AND (r2c6 = 6) AND (r2c7 = 2) AND (r2c8 = 7) AND (r3c2 = 1) AND (r4c1 = 9) AND (r4c4 = 7) AND (r4c5 = 6) AND (r4c6 = 2) AND (r5c1 = 7) AND (r6c3 = 8) AND (r7c1 = 2) AND (r7c3 = 3) AND (r7c7 = 8) AND (r8c4 = 1) AND (r8c5 = 9) AND (r8c9 = 5) AND (r9c3 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 5) AND (r1c4 = 8) AND (r1c5 = 3) AND (r2c7 = 7) AND (r2c8 = 1) AND (r3c2 = 3) AND (r4c1 = 7) AND (r4c4 = 4) AND (r4c7 = 8) AND (r5c1 = 1) AND (r5c3 = 2) AND (r7c2 = 8) AND (r7c4 = 6) AND (r7c7 = 4) AND (r8c1 = 9) AND (r8c6 = 2) AND (r9c5 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 7) AND (r1c9 = 5) AND (r2c2 = 3) AND (r2c8 = 7) AND (r3c1 = 2) AND (r3c3 = 5) AND (r3c8 = 3) AND (r3c9 = 8) AND (r4c8 = 8) AND (r4c9 = 9) AND (r5c1 = 5) AND (r5c3 = 8) AND (r5c4 = 2) AND (r5c6 = 9) AND (r5c7 = 7) AND (r5c9 = 4) AND (r6c1 = 3) AND (r7c1 = 6) AND (r7c3 = 4) AND (r7c4 = 9) AND (r7c5 = 8) AND (r7c6 = 7) AND (r7c7 = 5) AND (r8c1 = 9) AND (r8c4 = 5) AND (r9c4 = 4) AND (r9c6 = 6) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c2 = 6) AND (r1c3 = 8) AND (r1c7 = 1) AND (r2c2 = 7) AND (r2c4 = 4) AND (r2c6 = 8) AND (r2c8 = 5) AND (r3c4 = 6) AND (r4c3 = 6) AND (r4c4 = 1) AND (r4c5 = 8) AND (r4c6 = 3) AND (r4c9 = 7) AND (r5c3 = 7) AND (r6c1 = 3) AND (r6c5 = 5) AND (r6c7 = 2) AND (r6c9 = 1) AND (r7c6 = 7) AND (r8c4 = 8) AND (r8c6 = 2) AND (r8c7 = 5) AND (r9c6 = 5) AND (r9c7 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c8 = 1) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 5) AND (r3c5 = 6) AND (r4c4 = 3) AND (r4c8 = 7) AND (r5c3 = 2) AND (r5c7 = 6) AND (r6c2 = 1) AND (r6c6 = 5) AND (r7c5 = 8) AND (r7c7 = 2) AND (r8c1 = 7) AND (r8c2 = 3) AND (r8c4 = 9) AND (r9c2 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 7) AND (r1c9 = 2) AND (r2c5 = 4) AND (r2c6 = 5) AND (r2c8 = 7) AND (r3c3 = 9) AND (r4c1 = 3) AND (r4c5 = 5) AND (r4c7 = 8) AND (r5c1 = 4) AND (r5c2 = 8) AND (r5c4 = 9) AND (r5c6 = 1) AND (r5c9 = 7) AND (r6c3 = 7) AND (r6c6 = 4) AND (r6c7 = 2) AND (r6c9 = 9) AND (r7c5 = 1) AND (r7c7 = 3) AND (r8c8 = 5) AND (r9c2 = 3) AND (r9c4 = 8) AND (r9c5 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 9) AND (r1c8 = 7) AND (r2c8 = 2) AND (r2c9 = 4) AND (r3c1 = 1) AND (r4c2 = 2) AND (r4c3 = 9) AND (r4c9 = 5) AND (r5c6 = 1) AND (r5c7 = 6) AND (r6c2 = 4) AND (r6c5 = 8) AND (r7c4 = 4) AND (r7c5 = 3) AND (r8c1 = 5) AND (r8c7 = 8) AND (r9c4 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r2c2 = 9) AND (r2c3 = 3) AND (r3c2 = 7) AND (r3c8 = 3) AND (r4c3 = 9) AND (r4c5 = 6) AND (r4c8 = 7) AND (r4c9 = 4) AND (r5c3 = 6) AND (r5c5 = 7) AND (r5c7 = 3) AND (r5c8 = 9) AND (r6c2 = 3) AND (r6c4 = 5) AND (r6c7 = 6) AND (r6c8 = 8) AND (r7c1 = 9) AND (r7c5 = 8) AND (r7c6 = 2) AND (r7c7 = 4) AND (r8c2 = 8) AND (r8c3 = 2) AND (r8c5 = 3) AND (r8c8 = 5) AND (r8c9 = 7) AND (r9c2 = 6) AND (r9c3 = 4) AND (r9c4 = 7) AND (r9c5 = 5) AND (r9c8 = 2) AND (r9c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c5 = 5) AND (r1c8 = 6) AND (r1c9 = 9) AND (r2c1 = 6) AND (r2c8 = 4) AND (r3c2 = 1) AND (r3c5 = 8) AND (r3c6 = 9) AND (r3c9 = 3) AND (r4c4 = 1) AND (r5c4 = 3) AND (r6c2 = 8) AND (r6c8 = 9) AND (r7c1 = 4) AND (r7c2 = 6) AND (r8c3 = 7) AND (r8c6 = 3) AND (r8c9 = 8) AND (r9c2 = 5) AND (r9c3 = 8) AND (r9c4 = 7) AND (r9c6 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 7) AND (r1c5 = 9) AND (r1c6 = 4) AND (r2c2 = 1) AND (r2c6 = 7) AND (r3c3 = 9) AND (r3c4 = 2) AND (r3c5 = 1) AND (r4c1 = 2) AND (r4c4 = 5) AND (r4c6 = 9) AND (r5c3 = 8) AND (r5c4 = 6) AND (r6c1 = 9) AND (r6c2 = 5) AND (r6c6 = 1) AND (r6c8 = 2) AND (r6c9 = 7) AND (r7c1 = 8) AND (r7c6 = 2) AND (r7c7 = 6) AND (r8c1 = 1) AND (r8c5 = 5) AND (r8c6 = 8) AND (r8c9 = 2) AND (r9c4 = 7) AND (r9c5 = 4) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 1) AND (r1c4 = 6) AND (r1c5 = 2) AND (r2c1 = 5) AND (r2c8 = 4) AND (r2c9 = 3) AND (r3c5 = 9) AND (r4c1 = 7) AND (r4c8 = 8) AND (r5c3 = 5) AND (r5c9 = 4) AND (r6c4 = 1) AND (r7c6 = 3) AND (r7c7 = 6) AND (r8c2 = 9) AND (r8c7 = 2) AND (r9c1 = 8) AND (r9c6 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 5) AND (r1c3 = 8) AND (r1c6 = 6) AND (r1c7 = 3) AND (r1c8 = 2) AND (r1c9 = 4) AND (r2c1 = 9) AND (r2c2 = 2) AND (r2c3 = 3) AND (r2c6 = 8) AND (r2c7 = 5) AND (r2c8 = 6) AND (r3c5 = 5) AND (r4c9 = 8) AND (r5c2 = 8) AND (r5c3 = 7) AND (r5c6 = 9) AND (r7c2 = 4) AND (r7c4 = 6) AND (r7c6 = 7) AND (r7c8 = 5) AND (r8c1 = 3) AND (r8c5 = 9) AND (r8c6 = 5) AND (r8c8 = 8) AND (r8c9 = 2) AND (r9c2 = 9) AND (r9c3 = 5) AND (r9c5 = 8) AND (r9c7 = 6) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 3) AND (r1c5 = 7) AND (r1c7 = 8) AND (r2c4 = 4) AND (r2c6 = 3) AND (r3c1 = 2) AND (r3c4 = 5) AND (r3c5 = 6) AND (r3c6 = 8) AND (r3c9 = 3) AND (r4c2 = 6) AND (r4c3 = 2) AND (r4c7 = 5) AND (r4c8 = 3) AND (r5c1 = 1) AND (r5c3 = 5) AND (r5c7 = 9) AND (r5c9 = 4) AND (r6c2 = 3) AND (r6c3 = 9) AND (r6c7 = 2) AND (r6c8 = 1) AND (r7c1 = 3) AND (r7c4 = 6) AND (r7c5 = 2) AND (r7c6 = 7) AND (r7c9 = 5) AND (r8c4 = 9) AND (r8c6 = 5) AND (r9c3 = 7) AND (r9c5 = 8) AND (r9c7 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 3) AND (r1c3 = 8) AND (r2c1 = 7) AND (r2c6 = 8) AND (r3c1 = 6) AND (r3c2 = 4) AND (r3c3 = 9) AND (r3c4 = 3) AND (r3c5 = 1) AND (r3c6 = 7) AND (r3c8 = 2) AND (r4c1 = 1) AND (r4c2 = 7) AND (r4c5 = 3) AND (r4c6 = 6) AND (r4c8 = 8) AND (r4c9 = 2) AND (r5c1 = 3) AND (r5c3 = 6) AND (r5c4 = 2) AND (r5c6 = 1) AND (r5c8 = 7) AND (r5c9 = 9) AND (r6c5 = 7) AND (r7c1 = 4) AND (r7c2 = 9) AND (r7c8 = 1) AND (r8c2 = 6) AND (r8c3 = 1) AND (r8c5 = 9) AND (r8c8 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 5) AND (r1c8 = 8) AND (r2c2 = 1) AND (r2c6 = 3) AND (r3c1 = 3) AND (r3c3 = 7) AND (r3c4 = 6) AND (r4c2 = 9) AND (r4c4 = 1) AND (r4c5 = 7) AND (r4c6 = 6) AND (r4c7 = 3) AND (r5c4 = 9) AND (r5c6 = 8) AND (r5c8 = 1) AND (r6c1 = 2) AND (r7c2 = 6) AND (r8c2 = 8) AND (r8c6 = 1) AND (r8c8 = 6) AND (r9c2 = 3) AND (r9c4 = 2) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 8) AND (r1c7 = 4) AND (r1c9 = 3) AND (r2c1 = 9) AND (r2c4 = 3) AND (r2c7 = 7) AND (r3c2 = 1) AND (r3c3 = 5) AND (r3c6 = 2) AND (r4c1 = 6) AND (r4c8 = 9) AND (r4c9 = 5) AND (r5c2 = 3) AND (r5c3 = 7) AND (r6c4 = 8) AND (r7c7 = 8) AND (r7c8 = 3) AND (r7c9 = 2) AND (r8c2 = 2) AND (r8c5 = 9) AND (r9c1 = 8) AND (r9c4 = 7) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 7) AND (r1c4 = 2) AND (r1c6 = 4) AND (r1c8 = 5) AND (r2c2 = 4) AND (r2c9 = 2) AND (r3c2 = 2) AND (r3c5 = 8) AND (r3c9 = 6) AND (r4c3 = 7) AND (r4c9 = 5) AND (r5c1 = 8) AND (r5c4 = 5) AND (r6c1 = 6) AND (r6c3 = 3) AND (r6c8 = 7) AND (r7c3 = 9) AND (r7c4 = 7) AND (r8c1 = 3) AND (r8c3 = 2) AND (r8c5 = 5) AND (r8c8 = 6) AND (r9c3 = 5) AND (r9c4 = 3) AND (r9c7 = 9) AND (r9c8 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 8) AND (r1c8 = 7) AND (r2c1 = 2) AND (r2c2 = 6) AND (r3c2 = 4) AND (r3c5 = 6) AND (r3c6 = 5) AND (r4c3 = 7) AND (r5c6 = 2) AND (r5c8 = 3) AND (r6c6 = 3) AND (r6c8 = 4) AND (r6c9 = 5) AND (r7c4 = 3) AND (r8c3 = 2) AND (r8c4 = 8) AND (r8c5 = 9) AND (r8c6 = 7) AND (r9c2 = 5) AND (r9c9 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 3) AND (r1c5 = 8) AND (r1c8 = 7) AND (r1c9 = 1) AND (r2c2 = 6) AND (r2c3 = 7) AND (r3c1 = 8) AND (r5c1 = 7) AND (r5c2 = 2) AND (r5c3 = 9) AND (r5c5 = 3) AND (r5c6 = 1) AND (r5c8 = 6) AND (r5c9 = 4) AND (r6c1 = 3) AND (r6c2 = 8) AND (r6c3 = 1) AND (r7c3 = 8) AND (r7c5 = 1) AND (r7c7 = 7) AND (r7c8 = 4) AND (r8c2 = 1) AND (r8c3 = 2) AND (r8c4 = 6) AND (r8c8 = 8) AND (r8c9 = 3) AND (r9c1 = 6) AND (r9c4 = 3) AND (r9c5 = 4) AND (r9c8 = 1) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c8 = 4) AND (r2c5 = 8) AND (r2c9 = 7) AND (r3c4 = 1) AND (r3c5 = 4) AND (r3c6 = 6) AND (r3c7 = 9) AND (r3c9 = 8) AND (r4c1 = 2) AND (r4c5 = 6) AND (r4c9 = 3) AND (r5c3 = 1) AND (r5c5 = 9) AND (r5c9 = 6) AND (r6c2 = 8) AND (r6c3 = 6) AND (r6c4 = 3) AND (r6c5 = 7) AND (r6c7 = 4) AND (r7c5 = 1) AND (r7c7 = 7) AND (r8c1 = 9) AND (r8c2 = 4) AND (r8c8 = 3) AND (r8c9 = 1) AND (r9c6 = 7) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 3) AND (r1c5 = 2) AND (r1c6 = 6) AND (r2c7 = 4) AND (r2c9 = 1) AND (r3c1 = 5) AND (r4c1 = 2) AND (r4c8 = 6) AND (r5c6 = 5) AND (r5c8 = 3) AND (r6c2 = 4) AND (r6c4 = 1) AND (r7c4 = 4) AND (r7c5 = 1) AND (r7c7 = 7) AND (r8c4 = 8) AND (r9c1 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 4) AND (r1c7 = 8) AND (r1c8 = 1) AND (r2c1 = 9) AND (r2c4 = 6) AND (r2c6 = 7) AND (r3c3 = 8) AND (r3c6 = 2) AND (r3c8 = 6) AND (r4c6 = 1) AND (r4c8 = 4) AND (r4c9 = 2) AND (r5c2 = 3) AND (r6c1 = 6) AND (r6c2 = 4) AND (r7c1 = 8) AND (r7c2 = 1) AND (r8c7 = 4) AND (r8c8 = 3) AND (r9c3 = 7) AND (r9c4 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 3) AND (r1c3 = 4) AND (r1c6 = 5) AND (r1c8 = 8) AND (r2c2 = 5) AND (r2c5 = 9) AND (r2c8 = 4) AND (r2c9 = 3) AND (r3c1 = 9) AND (r3c2 = 8) AND (r3c4 = 2) AND (r3c9 = 5) AND (r4c1 = 3) AND (r4c5 = 7) AND (r4c9 = 8) AND (r5c2 = 4) AND (r5c6 = 3) AND (r5c7 = 6) AND (r5c8 = 9) AND (r6c2 = 9) AND (r6c5 = 6) AND (r6c7 = 2) AND (r7c1 = 6) AND (r7c5 = 5) AND (r7c6 = 7) AND (r8c5 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 2) AND (r1c5 = 5) AND (r1c6 = 4) AND (r1c7 = 3) AND (r1c8 = 6) AND (r1c9 = 1) AND (r2c4 = 2) AND (r3c5 = 1) AND (r3c6 = 9) AND (r4c4 = 4) AND (r4c6 = 8) AND (r5c2 = 4) AND (r5c4 = 3) AND (r5c5 = 2) AND (r5c6 = 5) AND (r5c7 = 1) AND (r5c8 = 8) AND (r6c5 = 6) AND (r6c8 = 9) AND (r6c9 = 4) AND (r7c1 = 3) AND (r7c4 = 1) AND (r7c6 = 2) AND (r7c9 = 5) AND (r8c9 = 3) AND (r9c6 = 6) AND (r9c7 = 2) AND (r9c8 = 1) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 1) AND (r1c5 = 6) AND (r2c2 = 3) AND (r2c7 = 5) AND (r2c9 = 4) AND (r3c5 = 2) AND (r4c8 = 7) AND (r4c9 = 2) AND (r5c3 = 1) AND (r5c4 = 5) AND (r5c5 = 7) AND (r5c7 = 9) AND (r6c2 = 4) AND (r6c8 = 1) AND (r7c2 = 9) AND (r7c3 = 2) AND (r8c4 = 7) AND (r8c7 = 6) AND (r8c8 = 3) AND (r9c8 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c3 = 5) AND (r1c9 = 2) AND (r2c4 = 9) AND (r2c6 = 1) AND (r3c1 = 3) AND (r4c2 = 6) AND (r4c4 = 7) AND (r4c7 = 4) AND (r5c1 = 2) AND (r5c5 = 5) AND (r6c8 = 6) AND (r7c4 = 3) AND (r7c5 = 8) AND (r8c2 = 1) AND (r8c7 = 7) AND (r9c2 = 4) AND (r9c8 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r2c2 = 7) AND (r2c7 = 8) AND (r2c9 = 4) AND (r3c5 = 9) AND (r3c6 = 8) AND (r3c7 = 3) AND (r3c9 = 2) AND (r4c1 = 6) AND (r4c4 = 1) AND (r4c7 = 9) AND (r5c3 = 7) AND (r5c8 = 3) AND (r6c1 = 2) AND (r6c2 = 8) AND (r6c6 = 3) AND (r6c7 = 6) AND (r7c2 = 3) AND (r7c4 = 9) AND (r7c5 = 4) AND (r7c6 = 6) AND (r7c9 = 8) AND (r8c2 = 2) AND (r9c1 = 1) AND (r9c3 = 4) AND (r9c4 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 6) AND (r1c8 = 1) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 2) AND (r3c5 = 5) AND (r4c4 = 6) AND (r4c8 = 7) AND (r5c3 = 8) AND (r5c7 = 9) AND (r6c2 = 5) AND (r6c6 = 3) AND (r7c5 = 6) AND (r7c7 = 5) AND (r8c1 = 7) AND (r8c2 = 1) AND (r8c4 = 9) AND (r9c2 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c3 = 3) AND (r1c7 = 6) AND (r1c8 = 4) AND (r2c1 = 1) AND (r2c2 = 2) AND (r2c5 = 6) AND (r2c7 = 5) AND (r3c1 = 5) AND (r3c4 = 8) AND (r3c5 = 9) AND (r3c6 = 3) AND (r3c8 = 2) AND (r3c9 = 1) AND (r4c5 = 3) AND (r5c2 = 6) AND (r5c5 = 2) AND (r5c6 = 5) AND (r5c8 = 1) AND (r5c9 = 3) AND (r6c2 = 1) AND (r6c6 = 9) AND (r6c8 = 5) AND (r7c1 = 4) AND (r7c4 = 3) AND (r7c6 = 1) AND (r8c2 = 5) AND (r9c4 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 5) AND (r1c3 = 3) AND (r1c5 = 9) AND (r2c7 = 8) AND (r2c9 = 1) AND (r3c1 = 2) AND (r4c1 = 4) AND (r4c5 = 2) AND (r4c8 = 5) AND (r5c2 = 1) AND (r5c4 = 8) AND (r6c2 = 6) AND (r6c4 = 7) AND (r7c4 = 4) AND (r7c6 = 7) AND (r7c7 = 6) AND (r8c8 = 3) AND (r9c1 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 1) AND (r1c4 = 7) AND (r1c7 = 2) AND (r1c9 = 5) AND (r2c8 = 6) AND (r2c9 = 3) AND (r3c3 = 3) AND (r3c5 = 6) AND (r4c1 = 5) AND (r4c4 = 3) AND (r4c9 = 7) AND (r6c3 = 8) AND (r6c4 = 2) AND (r6c6 = 7) AND (r6c7 = 3) AND (r6c8 = 9) AND (r7c8 = 7) AND (r8c1 = 2) AND (r8c4 = 5) AND (r8c7 = 1) AND (r9c2 = 6) AND (r9c4 = 8) AND (r9c5 = 3) AND (r9c6 = 1) AND (r9c7 = 5) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 9) AND (r1c4 = 5) AND (r1c6 = 6) AND (r1c7 = 4) AND (r1c8 = 2) AND (r2c1 = 2) AND (r2c2 = 3) AND (r2c7 = 8) AND (r2c9 = 5) AND (r3c2 = 5) AND (r3c3 = 4) AND (r3c5 = 3) AND (r3c8 = 6) AND (r3c9 = 9) AND (r4c3 = 8) AND (r4c4 = 6) AND (r4c5 = 7) AND (r4c6 = 5) AND (r6c4 = 3) AND (r6c5 = 2) AND (r6c6 = 9) AND (r6c9 = 6) AND (r7c2 = 4) AND (r7c3 = 2) AND (r7c5 = 9) AND (r7c6 = 3) AND (r7c7 = 6) AND (r8c4 = 4) AND (r8c5 = 6) AND (r9c1 = 3) AND (r9c4 = 2) AND (r9c6 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 3) AND (r1c5 = 5) AND (r2c3 = 9) AND (r2c7 = 1) AND (r3c6 = 9) AND (r3c9 = 6) AND (r4c4 = 8) AND (r4c9 = 5) AND (r5c5 = 1) AND (r5c7 = 8) AND (r5c8 = 3) AND (r6c2 = 3) AND (r6c3 = 2) AND (r6c8 = 7) AND (r7c1 = 1) AND (r7c2 = 8) AND (r7c7 = 3) AND (r8c3 = 7) AND (r8c8 = 2) AND (r9c2 = 5) AND (r9c7 = 7) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 6) AND (r1c7 = 8) AND (r1c9 = 7) AND (r2c3 = 3) AND (r2c8 = 4) AND (r3c1 = 2) AND (r3c2 = 9) AND (r3c5 = 7) AND (r3c9 = 6) AND (r4c4 = 9) AND (r4c7 = 2) AND (r4c9 = 3) AND (r5c4 = 2) AND (r5c5 = 6) AND (r5c9 = 9) AND (r7c1 = 3) AND (r7c2 = 8) AND (r7c5 = 2) AND (r8c3 = 7) AND (r8c7 = 1) AND (r8c9 = 4) AND (r9c4 = 1) AND (r9c8 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c8 = 1) AND (r2c6 = 1) AND (r2c8 = 2) AND (r2c9 = 3) AND (r3c5 = 5) AND (r4c4 = 6) AND (r4c8 = 4) AND (r5c3 = 3) AND (r5c7 = 5) AND (r6c2 = 7) AND (r6c6 = 2) AND (r7c5 = 4) AND (r7c7 = 8) AND (r8c1 = 2) AND (r8c2 = 1) AND (r8c4 = 8) AND (r8c8 = 7) AND (r9c2 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 5) AND (r1c5 = 7) AND (r1c7 = 4) AND (r1c8 = 1) AND (r2c3 = 7) AND (r2c4 = 2) AND (r2c7 = 3) AND (r2c9 = 9) AND (r3c5 = 4) AND (r3c7 = 7) AND (r3c9 = 2) AND (r4c3 = 8) AND (r4c6 = 2) AND (r5c4 = 3) AND (r5c5 = 9) AND (r5c7 = 2) AND (r5c8 = 4) AND (r6c2 = 3) AND (r6c4 = 4) AND (r6c9 = 5) AND (r7c4 = 9) AND (r7c5 = 2) AND (r7c7 = 5) AND (r8c4 = 8) AND (r8c5 = 1) AND (r8c6 = 4) AND (r8c9 = 7) AND (r9c1 = 8) AND (r9c6 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r2c2 = 7) AND (r2c4 = 6) AND (r2c5 = 3) AND (r3c3 = 9) AND (r3c4 = 8) AND (r3c8 = 6) AND (r4c7 = 7) AND (r4c8 = 3) AND (r5c3 = 2) AND (r5c4 = 3) AND (r5c7 = 5) AND (r5c9 = 9) AND (r6c3 = 6) AND (r6c5 = 1) AND (r6c7 = 2) AND (r7c1 = 2) AND (r7c3 = 3) AND (r7c6 = 1) AND (r8c1 = 9) AND (r8c5 = 6) AND (r8c9 = 8) AND (r9c2 = 8) AND (r9c3 = 1) AND (r9c4 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 9) AND (r2c4 = 3) AND (r2c5 = 6) AND (r2c7 = 1) AND (r3c5 = 1) AND (r3c6 = 9) AND (r3c7 = 5) AND (r4c1 = 5) AND (r4c8 = 9) AND (r4c9 = 2) AND (r5c5 = 7) AND (r6c4 = 6) AND (r6c9 = 3) AND (r7c4 = 9) AND (r7c7 = 7) AND (r7c8 = 5) AND (r8c5 = 5) AND (r8c6 = 1) AND (r8c8 = 2) AND (r9c2 = 6) AND (r9c5 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 3) AND (r1c3 = 7) AND (r2c1 = 9) AND (r2c2 = 4) AND (r2c3 = 6) AND (r2c9 = 3) AND (r3c1 = 1) AND (r3c4 = 7) AND (r4c1 = 2) AND (r4c2 = 8) AND (r4c3 = 1) AND (r4c4 = 4) AND (r5c3 = 3) AND (r5c6 = 6) AND (r6c1 = 4) AND (r7c5 = 1) AND (r7c7 = 9) AND (r7c9 = 2) AND (r8c3 = 2) AND (r8c4 = 9) AND (r8c6 = 4) AND (r8c9 = 6) AND (r9c1 = 3) AND (r9c2 = 1) AND (r9c5 = 8) AND (r9c8 = 4) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r2c1 = 4) AND (r2c2 = 2) AND (r2c3 = 9) AND (r2c5 = 8) AND (r2c6 = 3) AND (r3c2 = 8) AND (r3c4 = 5) AND (r3c6 = 4) AND (r4c5 = 2) AND (r4c7 = 4) AND (r4c8 = 7) AND (r5c2 = 4) AND (r5c4 = 8) AND (r5c6 = 9) AND (r5c8 = 5) AND (r6c3 = 2) AND (r6c4 = 1) AND (r6c7 = 3) AND (r6c9 = 8) AND (r7c2 = 9) AND (r8c1 = 8) AND (r8c5 = 7) AND (r8c6 = 2) AND (r8c9 = 4) AND (r9c4 = 9) AND (r9c5 = 1) AND (r9c6 = 8) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 2) AND (r1c7 = 4) AND (r1c9 = 9) AND (r2c2 = 4) AND (r2c8 = 5) AND (r2c9 = 2) AND (r3c3 = 5) AND (r3c7 = 8) AND (r3c8 = 7) AND (r4c2 = 8) AND (r4c8 = 9) AND (r4c9 = 6) AND (r5c3 = 7) AND (r5c6 = 9) AND (r5c7 = 2) AND (r5c8 = 3) AND (r6c3 = 2) AND (r6c5 = 3) AND (r6c7 = 7) AND (r6c9 = 8) AND (r7c2 = 5) AND (r7c5 = 8) AND (r7c7 = 9) AND (r8c1 = 2) AND (r8c3 = 6) AND (r9c3 = 8) AND (r9c4 = 5) AND (r9c6 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c5 = 6) AND (r2c3 = 2) AND (r2c7 = 6) AND (r3c2 = 1) AND (r3c6 = 9) AND (r3c7 = 5) AND (r3c9 = 3) AND (r4c2 = 7) AND (r4c7 = 8) AND (r5c1 = 1) AND (r5c8 = 3) AND (r6c3 = 9) AND (r6c9 = 5) AND (r7c2 = 8) AND (r7c6 = 3) AND (r7c9 = 9) AND (r8c1 = 7) AND (r8c3 = 5) AND (r8c6 = 2) AND (r8c7 = 1) AND (r8c9 = 6) AND (r9c1 = 6) AND (r9c8 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 3) AND (r1c8 = 1) AND (r2c1 = 7) AND (r2c4 = 5) AND (r3c1 = 2) AND (r3c5 = 4) AND (r4c2 = 3) AND (r4c3 = 9) AND (r4c6 = 8) AND (r5c8 = 6) AND (r5c9 = 2) AND (r6c2 = 1) AND (r7c1 = 5) AND (r7c4 = 6) AND (r7c9 = 7) AND (r8c2 = 8) AND (r8c7 = 9) AND (r9c5 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 5) AND (r1c3 = 1) AND (r1c5 = 7) AND (r1c8 = 6) AND (r1c9 = 3) AND (r2c2 = 6) AND (r2c8 = 2) AND (r3c2 = 2) AND (r3c3 = 3) AND (r3c5 = 6) AND (r3c7 = 7) AND (r3c8 = 9) AND (r5c2 = 1) AND (r5c7 = 3) AND (r5c8 = 5) AND (r6c3 = 9) AND (r6c8 = 4) AND (r7c1 = 6) AND (r7c4 = 4) AND (r7c6 = 9) AND (r7c7 = 5) AND (r8c1 = 5) AND (r8c2 = 9) AND (r8c4 = 6) AND (r8c5 = 3) AND (r8c8 = 7) AND (r8c9 = 4) AND (r9c3 = 4) AND (r9c4 = 7) AND (r9c5 = 5) AND (r9c8 = 3) AND (r9c9 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 7) AND (r1c8 = 9) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 2) AND (r3c5 = 5) AND (r4c4 = 4) AND (r4c8 = 2) AND (r5c3 = 6) AND (r5c7 = 7) AND (r6c2 = 5) AND (r6c6 = 3) AND (r7c5 = 6) AND (r7c7 = 5) AND (r8c1 = 8) AND (r8c2 = 1) AND (r8c4 = 9) AND (r9c2 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 1) AND (r1c8 = 8) AND (r2c6 = 1) AND (r2c8 = 2) AND (r2c9 = 3) AND (r3c3 = 4) AND (r3c5 = 5) AND (r4c4 = 2) AND (r4c8 = 6) AND (r5c3 = 7) AND (r5c7 = 8) AND (r6c2 = 5) AND (r6c6 = 9) AND (r7c5 = 7) AND (r7c7 = 5) AND (r8c1 = 6) AND (r8c2 = 3) AND (r8c4 = 8) AND (r9c2 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 2) AND (r1c3 = 7) AND (r1c5 = 3) AND (r1c6 = 4) AND (r1c8 = 6) AND (r1c9 = 5) AND (r2c6 = 8) AND (r2c9 = 2) AND (r3c3 = 4) AND (r3c7 = 7) AND (r4c1 = 4) AND (r4c9 = 3) AND (r5c1 = 8) AND (r5c3 = 2) AND (r5c7 = 6) AND (r5c8 = 4) AND (r6c2 = 7) AND (r6c9 = 8) AND (r7c2 = 2) AND (r7c3 = 1) AND (r7c5 = 8) AND (r7c8 = 5) AND (r8c1 = 6) AND (r8c2 = 4) AND (r8c5 = 2) AND (r8c6 = 5) AND (r8c7 = 3) AND (r9c1 = 5) AND (r9c6 = 7) AND (r9c9 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c8 = 8) AND (r2c1 = 3) AND (r2c4 = 5) AND (r2c6 = 7) AND (r2c7 = 1) AND (r3c6 = 1) AND (r3c8 = 6) AND (r3c9 = 3) AND (r4c3 = 2) AND (r5c1 = 8) AND (r5c3 = 7) AND (r5c7 = 2) AND (r5c8 = 3) AND (r6c1 = 5) AND (r6c5 = 7) AND (r7c2 = 8) AND (r7c5 = 4) AND (r7c6 = 3) AND (r7c8 = 2) AND (r7c9 = 1) AND (r8c1 = 1) AND (r8c3 = 5) AND (r8c9 = 6) AND (r9c1 = 4) AND (r9c2 = 3) AND (r9c7 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 3) AND (r1c8 = 1) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 5) AND (r3c5 = 7) AND (r4c4 = 4) AND (r4c8 = 5) AND (r5c3 = 7) AND (r5c7 = 6) AND (r6c2 = 8) AND (r6c6 = 1) AND (r7c5 = 5) AND (r7c7 = 8) AND (r8c1 = 1) AND (r8c2 = 2) AND (r8c4 = 3) AND (r9c2 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c5 = 3) AND (r1c6 = 1) AND (r2c1 = 3) AND (r2c4 = 4) AND (r2c5 = 2) AND (r2c8 = 6) AND (r3c4 = 6) AND (r3c6 = 9) AND (r4c5 = 7) AND (r4c6 = 3) AND (r4c7 = 4) AND (r5c2 = 7) AND (r5c4 = 1) AND (r5c6 = 2) AND (r5c7 = 5) AND (r5c8 = 3) AND (r6c4 = 5) AND (r6c5 = 4) AND (r6c8 = 1) AND (r7c2 = 1) AND (r7c7 = 3) AND (r8c1 = 5) AND (r8c2 = 3) AND (r8c7 = 6) AND (r8c8 = 9) AND (r9c2 = 6) AND (r9c3 = 9) AND (r9c5 = 1) AND (r9c6 = 4) AND (r9c7 = 2) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 8) AND (r1c7 = 4) AND (r2c2 = 2) AND (r2c6 = 1) AND (r2c8 = 9) AND (r3c5 = 7) AND (r3c9 = 5) AND (r4c4 = 4) AND (r4c7 = 8) AND (r5c5 = 5) AND (r5c9 = 7) AND (r6c1 = 1) AND (r6c6 = 9) AND (r6c8 = 2) AND (r7c1 = 9) AND (r7c6 = 6) AND (r7c7 = 1) AND (r7c8 = 3) AND (r8c1 = 2) AND (r9c1 = 6) AND (r9c3 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 3) AND (r1c3 = 4) AND (r1c4 = 6) AND (r1c7 = 9) AND (r1c8 = 2) AND (r1c9 = 1) AND (r2c1 = 2) AND (r3c2 = 1) AND (r3c3 = 9) AND (r3c9 = 5) AND (r4c2 = 4) AND (r4c3 = 2) AND (r4c9 = 9) AND (r5c2 = 9) AND (r5c3 = 6) AND (r6c1 = 3) AND (r6c4 = 9) AND (r6c8 = 6) AND (r7c2 = 2) AND (r7c3 = 1) AND (r7c5 = 4) AND (r7c6 = 9) AND (r7c8 = 5) AND (r8c4 = 5) AND (r8c6 = 6) AND (r8c8 = 1) AND (r9c4 = 2) AND (r9c5 = 1) AND (r9c7 = 7) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c9 = 4) AND (r2c2 = 3) AND (r2c3 = 1) AND (r2c6 = 9) AND (r2c9 = 7) AND (r3c1 = 2) AND (r3c2 = 9) AND (r3c6 = 1) AND (r4c2 = 7) AND (r4c6 = 6) AND (r5c6 = 2) AND (r5c9 = 9) AND (r6c4 = 7) AND (r6c5 = 4) AND (r7c1 = 5) AND (r7c5 = 1) AND (r7c8 = 2) AND (r8c2 = 6) AND (r8c5 = 9) AND (r8c8 = 7) AND (r8c9 = 3) AND (r9c3 = 3) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 4) AND (r1c6 = 2) AND (r1c7 = 5) AND (r1c8 = 6) AND (r2c4 = 7) AND (r2c9 = 3) AND (r3c2 = 1) AND (r4c1 = 6) AND (r4c5 = 9) AND (r4c6 = 8) AND (r5c5 = 1) AND (r6c9 = 4) AND (r7c7 = 1) AND (r7c8 = 8) AND (r8c1 = 4) AND (r8c4 = 3) AND (r9c1 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c4 = 4) AND (r1c5 = 2) AND (r1c6 = 6) AND (r1c7 = 1) AND (r2c2 = 4) AND (r2c4 = 3) AND (r2c5 = 7) AND (r2c8 = 2) AND (r3c3 = 6) AND (r3c5 = 1) AND (r3c6 = 5) AND (r3c8 = 7) AND (r4c1 = 6) AND (r5c2 = 8) AND (r5c4 = 5) AND (r6c1 = 4) AND (r6c2 = 5) AND (r6c3 = 2) AND (r6c5 = 6) AND (r6c6 = 3) AND (r7c1 = 5) AND (r7c4 = 7) AND (r7c9 = 2) AND (r8c1 = 7) AND (r8c9 = 1) AND (r9c1 = 3) AND (r9c3 = 4) AND (r9c4 = 6) AND (r9c5 = 5) AND (r9c6 = 2) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 9) AND (r1c7 = 3) AND (r1c9 = 6) AND (r2c1 = 7) AND (r2c4 = 6) AND (r2c6 = 4) AND (r2c7 = 8) AND (r3c1 = 6) AND (r3c2 = 1) AND (r3c5 = 3) AND (r3c9 = 7) AND (r4c1 = 1) AND (r4c2 = 6) AND (r4c7 = 4) AND (r4c9 = 3) AND (r5c6 = 1) AND (r5c7 = 7) AND (r6c2 = 8) AND (r6c4 = 4) AND (r6c5 = 9) AND (r6c8 = 1) AND (r7c2 = 9) AND (r7c5 = 4) AND (r8c9 = 4) AND (r9c1 = 2) AND (r9c2 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c2 = 3) AND (r1c5 = 7) AND (r1c6 = 6) AND (r1c7 = 5) AND (r1c8 = 9) AND (r2c2 = 6) AND (r2c3 = 5) AND (r2c5 = 4) AND (r3c4 = 5) AND (r3c5 = 9) AND (r3c7 = 3) AND (r4c2 = 1) AND (r4c6 = 8) AND (r4c7 = 4) AND (r4c8 = 5) AND (r5c1 = 3) AND (r5c2 = 7) AND (r5c4 = 6) AND (r5c6 = 4) AND (r5c7 = 1) AND (r5c9 = 9) AND (r6c5 = 1) AND (r6c6 = 9) AND (r6c8 = 7) AND (r6c9 = 3) AND (r7c2 = 9) AND (r7c5 = 8) AND (r8c2 = 5) AND (r8c5 = 6) AND (r8c6 = 7) AND (r8c7 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c2 = 4) AND (r1c6 = 6) AND (r1c8 = 2) AND (r2c3 = 6) AND (r2c9 = 9) AND (r3c7 = 1) AND (r4c5 = 9) AND (r4c8 = 3) AND (r5c1 = 3) AND (r5c2 = 6) AND (r5c7 = 9) AND (r6c3 = 2) AND (r6c4 = 8) AND (r7c2 = 9) AND (r7c7 = 4) AND (r7c8 = 7) AND (r8c2 = 7) AND (r8c3 = 1) AND (r8c5 = 4) AND (r8c7 = 6) AND (r8c9 = 8) AND (r9c1 = 2) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 2) AND (r1c4 = 3) AND (r1c6 = 8) AND (r1c8 = 6) AND (r2c1 = 8) AND (r2c5 = 7) AND (r2c9 = 2) AND (r3c3 = 6) AND (r3c4 = 5) AND (r3c6 = 2) AND (r3c7 = 8) AND (r4c1 = 6) AND (r4c3 = 2) AND (r4c7 = 7) AND (r4c9 = 3) AND (r5c2 = 9) AND (r5c8 = 2) AND (r6c1 = 3) AND (r6c3 = 5) AND (r6c7 = 9) AND (r6c9 = 4) AND (r7c3 = 7) AND (r7c4 = 2) AND (r7c6 = 1) AND (r7c7 = 6) AND (r8c1 = 5) AND (r8c5 = 6) AND (r8c9 = 1) AND (r9c2 = 6) AND (r9c4 = 4) AND (r9c6 = 5) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 2) AND (r1c3 = 4) AND (r1c8 = 3) AND (r1c9 = 1) AND (r2c1 = 9) AND (r2c3 = 6) AND (r2c4 = 4) AND (r2c5 = 5) AND (r3c3 = 3) AND (r3c5 = 7) AND (r3c8 = 6) AND (r5c1 = 4) AND (r5c8 = 7) AND (r5c9 = 9) AND (r6c4 = 5) AND (r6c5 = 6) AND (r7c1 = 1) AND (r7c4 = 2) AND (r8c1 = 6) AND (r8c2 = 7) AND (r8c5 = 4) AND (r9c5 = 9) AND (r9c6 = 7) AND (r9c8 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 6) AND (r1c7 = 4) AND (r2c1 = 9) AND (r2c3 = 3) AND (r3c4 = 4) AND (r3c8 = 2) AND (r4c9 = 9) AND (r5c1 = 2) AND (r5c7 = 3) AND (r6c5 = 3) AND (r6c6 = 1) AND (r6c7 = 7) AND (r7c1 = 5) AND (r7c2 = 9) AND (r7c3 = 7) AND (r8c1 = 4) AND (r8c4 = 9) AND (r9c2 = 2) AND (r9c7 = 6) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 5) AND (r1c4 = 7) AND (r1c8 = 3) AND (r2c2 = 8) AND (r2c6 = 9) AND (r2c9 = 5) AND (r3c4 = 1) AND (r3c7 = 6) AND (r3c9 = 2) AND (r4c8 = 9) AND (r5c5 = 6) AND (r6c4 = 3) AND (r6c6 = 1) AND (r7c2 = 7) AND (r7c8 = 8) AND (r8c1 = 6) AND (r8c4 = 2) AND (r8c5 = 8) AND (r8c7 = 3) AND (r9c1 = 1) AND (r9c2 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 7) AND (r2c2 = 4) AND (r2c7 = 1) AND (r2c9 = 3) AND (r3c6 = 9) AND (r3c8 = 6) AND (r3c9 = 5) AND (r4c3 = 4) AND (r5c2 = 3) AND (r5c3 = 7) AND (r5c4 = 2) AND (r5c8 = 9) AND (r6c4 = 1) AND (r7c1 = 7) AND (r7c5 = 1) AND (r7c7 = 6) AND (r8c3 = 5) AND (r8c6 = 7) AND (r8c7 = 2) AND (r9c5 = 6) AND (r9c6 = 5) AND (r9c8 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 2) AND (r1c5 = 3) AND (r1c8 = 5) AND (r2c2 = 8) AND (r2c9 = 1) AND (r3c2 = 9) AND (r4c1 = 5) AND (r4c6 = 1) AND (r4c8 = 3) AND (r5c5 = 8) AND (r5c7 = 9) AND (r6c1 = 2) AND (r7c2 = 4) AND (r7c4 = 6) AND (r7c7 = 8) AND (r8c1 = 7) AND (r8c4 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 6) AND (r1c5 = 4) AND (r1c6 = 1) AND (r1c7 = 8) AND (r1c9 = 5) AND (r2c3 = 8) AND (r2c6 = 2) AND (r2c7 = 4) AND (r2c9 = 1) AND (r3c1 = 1) AND (r3c3 = 4) AND (r3c4 = 5) AND (r3c5 = 8) AND (r3c8 = 6) AND (r4c3 = 1) AND (r4c5 = 3) AND (r4c9 = 4) AND (r6c6 = 9) AND (r6c9 = 3) AND (r7c2 = 2) AND (r7c3 = 6) AND (r8c1 = 5) AND (r8c3 = 9) AND (r8c5 = 1) AND (r8c6 = 4) AND (r8c8 = 2) AND (r8c9 = 6) AND (r9c1 = 4) AND (r9c5 = 6) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 3) AND (r1c4 = 2) AND (r2c1 = 5) AND (r2c5 = 8) AND (r2c7 = 6) AND (r2c9 = 4) AND (r3c9 = 9) AND (r4c1 = 3) AND (r4c4 = 4) AND (r4c5 = 5) AND (r5c3 = 8) AND (r5c4 = 1) AND (r5c5 = 9) AND (r5c6 = 6) AND (r6c1 = 4) AND (r6c5 = 3) AND (r6c7 = 1) AND (r6c9 = 6) AND (r7c1 = 1) AND (r7c4 = 6) AND (r7c7 = 9) AND (r7c8 = 5) AND (r7c9 = 8) AND (r8c4 = 5) AND (r9c1 = 8) AND (r9c2 = 6) AND (r9c7 = 4) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 6) AND (r1c3 = 4) AND (r1c4 = 3) AND (r1c5 = 1) AND (r1c9 = 5) AND (r2c2 = 2) AND (r2c5 = 5) AND (r2c7 = 6) AND (r2c9 = 4) AND (r3c3 = 8) AND (r3c5 = 6) AND (r3c6 = 4) AND (r3c8 = 2) AND (r4c3 = 1) AND (r4c7 = 9) AND (r4c9 = 2) AND (r5c2 = 3) AND (r6c1 = 8) AND (r6c5 = 2) AND (r6c6 = 6) AND (r6c9 = 1) AND (r7c4 = 5) AND (r7c5 = 9) AND (r8c1 = 3) AND (r8c6 = 8) AND (r9c1 = 9) AND (r9c5 = 4) AND (r9c6 = 3) AND (r9c8 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 1) AND (r1c8 = 7) AND (r1c9 = 3) AND (r2c4 = 5) AND (r2c5 = 6) AND (r2c7 = 8) AND (r2c8 = 4) AND (r3c4 = 3) AND (r3c6 = 8) AND (r3c7 = 6) AND (r4c5 = 5) AND (r4c6 = 2) AND (r4c7 = 7) AND (r4c9 = 6) AND (r5c4 = 7) AND (r5c5 = 1) AND (r5c8 = 3) AND (r7c1 = 2) AND (r7c2 = 7) AND (r7c8 = 6) AND (r7c9 = 8) AND (r8c2 = 4) AND (r8c3 = 5) AND (r8c4 = 1) AND (r9c1 = 6) AND (r9c2 = 8) AND (r9c3 = 3) AND (r9c6 = 7) AND (r9c9 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c5 = 5) AND (r1c8 = 1) AND (r2c1 = 5) AND (r2c2 = 8) AND (r3c5 = 7) AND (r4c4 = 7) AND (r4c5 = 2) AND (r4c6 = 4) AND (r4c7 = 1) AND (r4c8 = 8) AND (r5c1 = 1) AND (r5c5 = 8) AND (r5c9 = 9) AND (r6c2 = 7) AND (r6c4 = 1) AND (r6c5 = 3) AND (r6c8 = 4) AND (r7c1 = 3) AND (r7c3 = 2) AND (r7c5 = 9) AND (r7c7 = 8) AND (r7c8 = 5) AND (r7c9 = 4) AND (r8c2 = 9) AND (r8c3 = 7) AND (r8c7 = 2) AND (r9c1 = 8) AND (r9c3 = 5) AND (r9c6 = 2) AND (r9c8 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c6 = 7) AND (r1c9 = 2) AND (r2c1 = 5) AND (r2c2 = 2) AND (r2c4 = 9) AND (r2c5 = 3) AND (r2c7 = 4) AND (r3c4 = 5) AND (r3c9 = 7) AND (r4c1 = 9) AND (r4c2 = 3) AND (r4c9 = 4) AND (r5c9 = 1) AND (r6c6 = 1) AND (r6c7 = 3) AND (r7c3 = 4) AND (r7c5 = 2) AND (r8c1 = 2) AND (r8c2 = 9) AND (r8c5 = 7) AND (r9c1 = 1) AND (r9c5 = 8) AND (r9c6 = 5) AND (r9c8 = 2) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c7 = 7) AND (r1c8 = 5) AND (r1c9 = 3) AND (r2c2 = 7) AND (r2c3 = 9) AND (r2c6 = 3) AND (r2c7 = 2) AND (r2c8 = 1) AND (r3c3 = 5) AND (r4c5 = 2) AND (r5c3 = 4) AND (r5c5 = 3) AND (r5c7 = 1) AND (r5c9 = 7) AND (r6c1 = 3) AND (r6c3 = 6) AND (r6c4 = 1) AND (r6c7 = 4) AND (r6c8 = 2) AND (r7c1 = 2) AND (r7c3 = 3) AND (r7c6 = 6) AND (r7c7 = 5) AND (r7c9 = 1) AND (r8c2 = 6) AND (r8c3 = 7) AND (r8c5 = 1) AND (r8c8 = 4) AND (r8c9 = 2) AND (r9c7 = 6) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 3) AND (r1c3 = 7) AND (r1c8 = 5) AND (r2c3 = 9) AND (r2c5 = 6) AND (r2c8 = 1) AND (r3c6 = 1) AND (r3c7 = 3) AND (r4c2 = 7) AND (r5c3 = 1) AND (r5c4 = 2) AND (r5c6 = 7) AND (r5c9 = 5) AND (r6c5 = 3) AND (r6c7 = 8) AND (r6c9 = 6) AND (r7c6 = 3) AND (r8c4 = 7) AND (r8c5 = 8) AND (r9c1 = 6) AND (r9c8 = 9) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 3) AND (r1c7 = 5) AND (r1c8 = 9) AND (r2c2 = 5) AND (r2c3 = 1) AND (r2c5 = 6) AND (r2c6 = 3) AND (r3c3 = 9) AND (r3c5 = 2) AND (r5c2 = 7) AND (r5c3 = 3) AND (r5c5 = 5) AND (r5c8 = 2) AND (r6c3 = 2) AND (r6c7 = 1) AND (r6c8 = 7) AND (r7c2 = 9) AND (r7c4 = 7) AND (r7c6 = 6) AND (r7c7 = 3) AND (r7c8 = 5) AND (r8c1 = 7) AND (r8c2 = 8) AND (r9c5 = 8) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r2c4 = 4) AND (r2c8 = 5) AND (r3c1 = 8) AND (r3c2 = 5) AND (r3c3 = 9) AND (r3c4 = 2) AND (r4c3 = 3) AND (r4c4 = 5) AND (r4c7 = 4) AND (r4c8 = 9) AND (r5c7 = 5) AND (r5c9 = 6) AND (r6c3 = 7) AND (r6c4 = 9) AND (r6c5 = 2) AND (r6c6 = 4) AND (r6c8 = 3) AND (r6c9 = 8) AND (r7c6 = 2) AND (r7c8 = 8) AND (r8c1 = 7) AND (r8c4 = 8) AND (r8c5 = 5) AND (r8c7 = 9) AND (r8c8 = 4) AND (r9c2 = 3) AND (r9c4 = 7) AND (r9c5 = 4) AND (r9c8 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 9) AND (r1c7 = 6) AND (r2c1 = 8) AND (r2c3 = 6) AND (r2c4 = 7) AND (r2c5 = 4) AND (r2c6 = 5) AND (r2c8 = 2) AND (r2c9 = 9) AND (r3c3 = 4) AND (r3c6 = 3) AND (r3c8 = 7) AND (r3c9 = 5) AND (r4c1 = 4) AND (r4c4 = 3) AND (r4c5 = 7) AND (r4c6 = 9) AND (r4c8 = 6) AND (r5c6 = 4) AND (r6c1 = 7) AND (r6c5 = 8) AND (r6c8 = 5) AND (r7c3 = 8) AND (r7c4 = 4) AND (r7c6 = 6) AND (r8c1 = 3) AND (r8c5 = 5) AND (r8c6 = 8) AND (r9c4 = 2) AND (r9c5 = 3) AND (r9c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c5 = 7) AND (r3c3 = 3) AND (r3c5 = 2) AND (r3c8 = 5) AND (r4c2 = 6) AND (r4c5 = 4) AND (r4c9 = 2) AND (r5c3 = 8) AND (r5c4 = 5) AND (r5c6 = 9) AND (r6c4 = 6) AND (r7c1 = 6) AND (r7c8 = 9) AND (r8c3 = 2) AND (r8c5 = 3) AND (r8c9 = 4) AND (r9c1 = 4) AND (r9c2 = 7) AND (r9c4 = 8) AND (r9c7 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 3) AND (r1c4 = 4) AND (r1c6 = 6) AND (r2c2 = 9) AND (r2c7 = 7) AND (r4c1 = 6) AND (r4c3 = 4) AND (r4c4 = 1) AND (r5c5 = 7) AND (r5c7 = 2) AND (r5c9 = 9) AND (r6c7 = 5) AND (r7c5 = 3) AND (r7c8 = 8) AND (r8c1 = 5) AND (r8c2 = 2) AND (r9c4 = 8) AND (r9c8 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 7) AND (r1c5 = 2) AND (r2c2 = 8) AND (r2c6 = 6) AND (r3c6 = 3) AND (r3c9 = 6) AND (r4c3 = 3) AND (r4c5 = 4) AND (r4c7 = 7) AND (r4c8 = 8) AND (r5c1 = 2) AND (r5c5 = 1) AND (r6c2 = 6) AND (r6c9 = 5) AND (r7c4 = 1) AND (r7c7 = 3) AND (r7c8 = 7) AND (r8c5 = 5) AND (r9c3 = 8) AND (r9c6 = 7) AND (r9c8 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c8 = 8) AND (r2c1 = 3) AND (r2c2 = 5) AND (r2c3 = 1) AND (r2c5 = 7) AND (r3c6 = 9) AND (r3c7 = 7) AND (r3c9 = 3) AND (r4c3 = 7) AND (r4c4 = 1) AND (r4c6 = 8) AND (r4c7 = 5) AND (r5c5 = 3) AND (r5c7 = 2) AND (r6c2 = 8) AND (r6c6 = 5) AND (r6c8 = 9) AND (r7c7 = 1) AND (r7c8 = 5) AND (r7c9 = 2) AND (r8c3 = 3) AND (r8c4 = 4) AND (r8c6 = 1) AND (r9c4 = 9) AND (r9c5 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 3) AND (r1c9 = 8) AND (r2c1 = 7) AND (r2c2 = 2) AND (r2c4 = 9) AND (r2c9 = 6) AND (r3c4 = 1) AND (r4c2 = 8) AND (r4c6 = 6) AND (r5c3 = 7) AND (r5c5 = 5) AND (r5c8 = 6) AND (r6c1 = 3) AND (r6c5 = 2) AND (r7c1 = 5) AND (r7c3 = 8) AND (r7c4 = 7) AND (r7c5 = 1) AND (r8c6 = 9) AND (r9c1 = 2) AND (r9c3 = 6) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 5) AND (r1c3 = 2) AND (r1c4 = 9) AND (r2c7 = 8) AND (r3c8 = 4) AND (r3c9 = 6) AND (r4c2 = 1) AND (r4c6 = 2) AND (r4c9 = 3) AND (r5c1 = 3) AND (r5c2 = 7) AND (r6c6 = 4) AND (r7c8 = 7) AND (r8c1 = 6) AND (r8c4 = 5) AND (r8c6 = 1) AND (r9c1 = 4) AND (r9c4 = 3) AND (r9c6 = 9) AND (r9c7 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c5 = 6) AND (r1c6 = 4) AND (r1c8 = 2) AND (r1c9 = 5) AND (r2c2 = 5) AND (r2c6 = 9) AND (r2c9 = 1) AND (r3c5 = 2) AND (r3c8 = 4) AND (r3c9 = 9) AND (r4c1 = 5) AND (r4c3 = 6) AND (r4c6 = 3) AND (r4c8 = 1) AND (r5c1 = 4) AND (r5c3 = 2) AND (r6c2 = 1) AND (r7c1 = 3) AND (r7c2 = 6) AND (r7c3 = 9) AND (r7c4 = 4) AND (r7c8 = 5) AND (r8c3 = 5) AND (r8c6 = 6) AND (r9c1 = 7) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c5 = 6) AND (r1c6 = 5) AND (r1c9 = 7) AND (r2c1 = 5) AND (r2c6 = 3) AND (r2c8 = 6) AND (r2c9 = 8) AND (r3c3 = 8) AND (r3c4 = 4) AND (r3c9 = 9) AND (r4c3 = 2) AND (r5c5 = 5) AND (r5c9 = 3) AND (r6c3 = 6) AND (r6c6 = 7) AND (r7c5 = 9) AND (r7c7 = 2) AND (r8c4 = 3) AND (r8c7 = 4) AND (r9c1 = 6) AND (r9c8 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c4 = 3) AND (r1c8 = 6) AND (r2c5 = 8) AND (r2c7 = 5) AND (r3c2 = 1) AND (r4c1 = 8) AND (r4c3 = 9) AND (r4c4 = 6) AND (r4c7 = 4) AND (r5c4 = 1) AND (r5c6 = 2) AND (r6c1 = 5) AND (r7c4 = 7) AND (r7c8 = 3) AND (r7c9 = 2) AND (r8c1 = 4) AND (r8c5 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 4) AND (r1c8 = 6) AND (r2c4 = 1) AND (r2c5 = 2) AND (r2c6 = 9) AND (r2c8 = 8) AND (r2c9 = 4) AND (r3c3 = 2) AND (r4c3 = 5) AND (r4c7 = 4) AND (r5c2 = 2) AND (r5c4 = 4) AND (r5c5 = 1) AND (r5c7 = 8) AND (r5c8 = 5) AND (r6c2 = 6) AND (r6c4 = 5) AND (r6c6 = 8) AND (r6c8 = 2) AND (r7c1 = 2) AND (r7c2 = 1) AND (r7c3 = 6) AND (r7c6 = 5) AND (r8c2 = 8) AND (r8c4 = 2) AND (r8c5 = 3) AND (r9c2 = 3) AND (r9c3 = 4) AND (r9c4 = 8) AND (r9c6 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 8) AND (r1c7 = 1) AND (r1c9 = 4) AND (r2c1 = 7) AND (r2c2 = 3) AND (r4c5 = 7) AND (r4c6 = 2) AND (r4c7 = 6) AND (r5c2 = 1) AND (r5c3 = 3) AND (r7c3 = 4) AND (r7c4 = 3) AND (r7c5 = 1) AND (r8c1 = 2) AND (r8c7 = 5) AND (r8c8 = 7) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 9) AND (r1c5 = 4) AND (r1c8 = 8) AND (r2c2 = 4) AND (r2c9 = 7) AND (r3c4 = 6) AND (r3c9 = 2) AND (r4c3 = 5) AND (r4c7 = 7) AND (r4c8 = 4) AND (r5c1 = 9) AND (r5c2 = 6) AND (r5c7 = 5) AND (r6c4 = 2) AND (r7c2 = 5) AND (r7c5 = 2) AND (r7c9 = 8) AND (r8c3 = 4) AND (r8c5 = 8) AND (r8c6 = 3) AND (r9c2 = 8) AND (r9c4 = 9) AND (r9c5 = 7) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 2) AND (r1c5 = 6) AND (r1c8 = 8) AND (r2c1 = 9) AND (r2c3 = 4) AND (r4c2 = 8) AND (r4c4 = 5) AND (r4c8 = 6) AND (r5c1 = 7) AND (r5c6 = 9) AND (r6c9 = 1) AND (r7c2 = 2) AND (r7c4 = 6) AND (r8c5 = 3) AND (r8c7 = 9) AND (r9c1 = 1) AND (r9c7 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 4) AND (r1c3 = 8) AND (r1c4 = 9) AND (r1c6 = 7) AND (r1c7 = 1) AND (r3c4 = 4) AND (r3c5 = 3) AND (r3c6 = 1) AND (r4c6 = 4) AND (r5c5 = 9) AND (r5c7 = 7) AND (r6c1 = 6) AND (r6c5 = 2) AND (r6c6 = 3) AND (r7c2 = 7) AND (r7c6 = 8) AND (r7c7 = 3) AND (r7c9 = 9) AND (r8c1 = 1) AND (r8c3 = 3) AND (r8c5 = 7) AND (r8c6 = 2) AND (r8c7 = 8) AND (r8c9 = 4) AND (r9c2 = 8) AND (r9c3 = 4) AND (r9c7 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 7) AND (r1c3 = 5) AND (r1c7 = 8) AND (r1c8 = 2) AND (r2c1 = 2) AND (r2c2 = 9) AND (r2c3 = 8) AND (r2c4 = 7) AND (r3c1 = 4) AND (r3c2 = 3) AND (r3c8 = 5) AND (r3c9 = 9) AND (r4c1 = 8) AND (r4c4 = 3) AND (r4c5 = 4) AND (r4c6 = 6) AND (r5c4 = 2) AND (r5c7 = 3) AND (r6c5 = 5) AND (r6c6 = 7) AND (r7c5 = 6) AND (r7c6 = 4) AND (r8c4 = 8) AND (r8c6 = 9) AND (r8c8 = 4) AND (r9c4 = 5) AND (r9c5 = 3) AND (r9c7 = 6) AND (r9c8 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 1) AND (r1c8 = 8) AND (r2c8 = 6) AND (r3c3 = 8) AND (r3c4 = 4) AND (r3c7 = 1) AND (r4c1 = 5) AND (r4c3 = 6) AND (r4c7 = 4) AND (r5c5 = 9) AND (r5c8 = 5) AND (r5c9 = 7) AND (r6c5 = 8) AND (r6c6 = 4) AND (r7c4 = 8) AND (r7c6 = 7) AND (r7c7 = 2) AND (r8c2 = 2) AND (r8c3 = 7) AND (r8c5 = 1) AND (r9c2 = 5) AND (r9c4 = 6) AND (r9c6 = 2) AND (r9c7 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 6) AND (r1c4 = 3) AND (r1c6 = 1) AND (r2c5 = 8) AND (r2c9 = 1) AND (r3c2 = 8) AND (r3c4 = 9) AND (r3c5 = 5) AND (r3c6 = 7) AND (r3c8 = 3) AND (r4c1 = 9) AND (r4c3 = 8) AND (r4c5 = 3) AND (r4c6 = 4) AND (r4c8 = 6) AND (r5c6 = 9) AND (r6c4 = 1) AND (r6c5 = 7) AND (r6c6 = 8) AND (r6c8 = 9) AND (r6c9 = 5) AND (r7c1 = 8) AND (r7c2 = 6) AND (r7c6 = 5) AND (r7c7 = 7) AND (r7c8 = 1) AND (r8c1 = 7) AND (r8c3 = 1) AND (r8c6 = 3) AND (r8c7 = 5) AND (r8c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c8 = 4) AND (r2c1 = 6) AND (r2c4 = 3) AND (r2c5 = 8) AND (r2c9 = 7) AND (r3c4 = 7) AND (r3c5 = 9) AND (r3c6 = 6) AND (r4c4 = 6) AND (r4c8 = 3) AND (r5c5 = 1) AND (r6c3 = 7) AND (r6c4 = 4) AND (r6c9 = 2) AND (r7c2 = 4) AND (r7c4 = 8) AND (r7c9 = 6) AND (r8c1 = 3) AND (r8c2 = 1) AND (r9c2 = 9) AND (r9c7 = 2) AND (r9c8 = 1) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 1) AND (r1c7 = 6) AND (r2c2 = 4) AND (r2c3 = 3) AND (r2c8 = 8) AND (r2c9 = 5) AND (r3c1 = 6) AND (r3c4 = 5) AND (r3c9 = 2) AND (r4c6 = 3) AND (r4c7 = 2) AND (r5c3 = 5) AND (r5c5 = 1) AND (r5c6 = 7) AND (r5c8 = 6) AND (r5c9 = 8) AND (r6c4 = 8) AND (r6c6 = 5) AND (r6c9 = 1) AND (r7c3 = 2) AND (r7c6 = 6) AND (r7c7 = 1) AND (r7c8 = 3) AND (r7c9 = 4) AND (r8c1 = 4) AND (r8c6 = 1) AND (r8c8 = 2) AND (r8c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c5 = 2) AND (r1c6 = 9) AND (r1c7 = 3) AND (r1c8 = 6) AND (r2c1 = 3) AND (r2c2 = 8) AND (r2c4 = 1) AND (r2c5 = 4) AND (r2c8 = 2) AND (r3c2 = 9) AND (r4c2 = 1) AND (r4c3 = 9) AND (r4c4 = 8) AND (r4c7 = 4) AND (r5c4 = 4) AND (r5c5 = 9) AND (r5c9 = 7) AND (r6c6 = 3) AND (r7c1 = 8) AND (r7c3 = 6) AND (r8c3 = 7) AND (r8c7 = 8) AND (r9c6 = 2) AND (r9c8 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 1) AND (r1c8 = 6) AND (r2c1 = 6) AND (r2c5 = 7) AND (r2c6 = 2) AND (r3c9 = 9) AND (r4c1 = 1) AND (r4c2 = 8) AND (r4c4 = 2) AND (r4c7 = 5) AND (r6c6 = 5) AND (r6c8 = 9) AND (r6c9 = 4) AND (r7c1 = 7) AND (r7c2 = 5) AND (r7c7 = 9) AND (r8c1 = 4) AND (r8c6 = 6) AND (r8c7 = 8) AND (r8c8 = 5) AND (r9c3 = 6) AND (r9c5 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 6) AND (r1c6 = 7) AND (r1c7 = 5) AND (r2c5 = 5) AND (r2c8 = 6) AND (r2c9 = 4) AND (r3c2 = 5) AND (r3c5 = 6) AND (r3c7 = 9) AND (r3c8 = 8) AND (r3c9 = 1) AND (r4c1 = 1) AND (r5c3 = 7) AND (r5c4 = 9) AND (r5c9 = 2) AND (r6c2 = 9) AND (r6c7 = 1) AND (r7c3 = 4) AND (r7c5 = 1) AND (r7c6 = 5) AND (r7c9 = 9) AND (r8c1 = 8) AND (r8c5 = 7) AND (r8c9 = 6) AND (r9c6 = 2) AND (r9c8 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c5 = 6) AND (r2c2 = 2) AND (r2c3 = 7) AND (r2c5 = 9) AND (r2c6 = 1) AND (r2c9 = 5) AND (r3c3 = 3) AND (r3c4 = 7) AND (r3c6 = 8) AND (r4c8 = 3) AND (r5c1 = 5) AND (r5c3 = 6) AND (r5c5 = 2) AND (r5c6 = 9) AND (r5c7 = 7) AND (r6c1 = 2) AND (r6c3 = 1) AND (r6c6 = 7) AND (r7c1 = 3) AND (r7c3 = 9) AND (r7c6 = 6) AND (r7c7 = 1) AND (r7c8 = 2) AND (r8c2 = 6) AND (r8c3 = 5) AND (r8c5 = 1) AND (r8c6 = 2) AND (r9c1 = 1) AND (r9c4 = 9) AND (r9c5 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 3) AND (r1c7 = 7) AND (r1c8 = 6) AND (r2c1 = 8) AND (r2c5 = 2) AND (r2c6 = 6) AND (r2c8 = 5) AND (r3c1 = 4) AND (r3c2 = 5) AND (r4c8 = 1) AND (r5c3 = 2) AND (r5c4 = 8) AND (r5c6 = 5) AND (r5c8 = 3) AND (r5c9 = 7) AND (r6c9 = 8) AND (r7c1 = 2) AND (r7c3 = 8) AND (r7c4 = 6) AND (r8c2 = 3) AND (r8c4 = 5) AND (r8c7 = 6) AND (r8c8 = 2) AND (r9c3 = 7) AND (r9c6 = 2) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r2c2 = 1) AND (r2c5 = 8) AND (r2c6 = 6) AND (r2c7 = 4) AND (r3c2 = 4) AND (r4c3 = 8) AND (r4c7 = 1) AND (r4c8 = 3) AND (r5c1 = 5) AND (r5c2 = 3) AND (r6c2 = 7) AND (r6c3 = 1) AND (r6c5 = 3) AND (r6c7 = 5) AND (r7c3 = 7) AND (r7c4 = 4) AND (r7c8 = 1) AND (r8c2 = 5) AND (r8c3 = 4) AND (r8c4 = 7) AND (r8c5 = 9) AND (r8c7 = 6) AND (r8c9 = 8) AND (r9c2 = 6) AND (r9c3 = 9) AND (r9c4 = 8) AND (r9c5 = 5) AND (r9c6 = 1) AND (r9c7 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 7) AND (r1c3 = 8) AND (r1c5 = 2) AND (r2c8 = 9) AND (r2c9 = 1) AND (r3c1 = 3) AND (r4c2 = 4) AND (r4c3 = 6) AND (r5c5 = 3) AND (r5c7 = 7) AND (r6c4 = 5) AND (r7c2 = 5) AND (r7c4 = 9) AND (r7c6 = 6) AND (r8c4 = 4) AND (r8c8 = 1) AND (r9c1 = 2) AND (r9c7 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 3) AND (r1c9 = 2) AND (r2c3 = 8) AND (r3c5 = 5) AND (r4c9 = 4) AND (r5c2 = 5) AND (r5c5 = 7) AND (r5c8 = 2) AND (r6c2 = 7) AND (r6c4 = 3) AND (r6c5 = 8) AND (r6c6 = 4) AND (r6c8 = 5) AND (r7c2 = 9) AND (r7c3 = 7) AND (r7c6 = 8) AND (r7c9 = 5) AND (r8c2 = 8) AND (r8c3 = 2) AND (r8c5 = 1) AND (r8c6 = 7) AND (r8c8 = 4) AND (r9c2 = 1) AND (r9c3 = 5) AND (r9c4 = 4) AND (r9c5 = 2) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 7) AND (r1c6 = 5) AND (r2c1 = 6) AND (r2c9 = 4) AND (r3c1 = 8) AND (r3c2 = 5) AND (r3c6 = 7) AND (r4c6 = 8) AND (r4c9 = 6) AND (r5c1 = 9) AND (r5c2 = 6) AND (r5c5 = 4) AND (r5c7 = 5) AND (r6c3 = 1) AND (r6c6 = 3) AND (r6c7 = 8) AND (r7c3 = 4) AND (r7c5 = 7) AND (r8c1 = 3) AND (r8c4 = 8) AND (r8c7 = 9) AND (r8c9 = 7) AND (r9c2 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 8) AND (r1c5 = 7) AND (r1c8 = 2) AND (r2c7 = 6) AND (r2c9 = 4) AND (r3c3 = 6) AND (r3c4 = 9) AND (r3c6 = 5) AND (r3c7 = 3) AND (r4c4 = 5) AND (r4c6 = 7) AND (r5c5 = 9) AND (r5c8 = 8) AND (r5c9 = 2) AND (r6c7 = 5) AND (r7c1 = 2) AND (r7c2 = 3) AND (r7c6 = 4) AND (r7c9 = 9) AND (r8c1 = 4) AND (r8c4 = 7) AND (r8c5 = 6) AND (r8c9 = 5) AND (r9c1 = 5) AND (r9c5 = 3) AND (r9c6 = 9) AND (r9c8 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 6) AND (r1c4 = 8) AND (r1c6 = 9) AND (r1c9 = 5) AND (r2c1 = 5) AND (r2c6 = 4) AND (r3c1 = 9) AND (r3c2 = 2) AND (r3c7 = 6) AND (r4c3 = 1) AND (r4c7 = 3) AND (r5c3 = 3) AND (r5c5 = 8) AND (r5c9 = 6) AND (r6c1 = 6) AND (r6c4 = 1) AND (r6c5 = 9) AND (r6c8 = 5) AND (r6c9 = 8) AND (r7c9 = 3) AND (r8c6 = 2) AND (r9c4 = 6) AND (r9c7 = 1) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 6) AND (r1c9 = 7) AND (r2c4 = 7) AND (r2c5 = 9) AND (r2c8 = 8) AND (r2c9 = 3) AND (r3c5 = 8) AND (r3c7 = 5) AND (r3c8 = 4) AND (r4c2 = 4) AND (r4c3 = 3) AND (r4c5 = 1) AND (r4c9 = 5) AND (r5c3 = 5) AND (r5c8 = 6) AND (r6c2 = 6) AND (r6c5 = 3) AND (r6c7 = 4) AND (r7c1 = 6) AND (r7c4 = 3) AND (r7c6 = 9) AND (r7c7 = 8) AND (r8c6 = 5) AND (r8c8 = 9) AND (r9c1 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 2) AND (r2c2 = 4) AND (r2c6 = 6) AND (r2c8 = 7) AND (r2c9 = 1) AND (r3c3 = 9) AND (r3c4 = 3) AND (r3c7 = 4) AND (r4c4 = 9) AND (r4c5 = 4) AND (r5c3 = 6) AND (r5c6 = 1) AND (r5c9 = 7) AND (r6c3 = 1) AND (r6c5 = 2) AND (r6c6 = 7) AND (r7c1 = 7) AND (r7c3 = 4) AND (r7c4 = 1) AND (r7c5 = 6) AND (r7c8 = 9) AND (r7c9 = 5) AND (r8c1 = 9) AND (r9c1 = 6) AND (r9c2 = 1) AND (r9c5 = 5) AND (r9c8 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 7) AND (r1c6 = 1) AND (r1c8 = 4) AND (r2c1 = 8) AND (r2c3 = 9) AND (r2c4 = 2) AND (r2c8 = 1) AND (r3c4 = 8) AND (r3c6 = 7) AND (r3c7 = 2) AND (r3c9 = 5) AND (r4c1 = 5) AND (r5c3 = 4) AND (r5c4 = 6) AND (r5c8 = 8) AND (r6c3 = 7) AND (r6c4 = 4) AND (r7c4 = 9) AND (r7c8 = 6) AND (r7c9 = 8) AND (r8c1 = 9) AND (r8c3 = 5) AND (r8c4 = 1) AND (r8c6 = 8) AND (r8c7 = 4) AND (r8c8 = 7) AND (r9c1 = 4) AND (r9c3 = 8) AND (r9c5 = 2) AND (r9c8 = 5) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c3 = 8) AND (r1c9 = 4) AND (r2c1 = 6) AND (r2c3 = 2) AND (r2c7 = 5) AND (r2c8 = 8) AND (r3c1 = 5) AND (r3c2 = 4) AND (r3c5 = 2) AND (r3c7 = 1) AND (r3c8 = 6) AND (r3c9 = 7) AND (r4c7 = 8) AND (r4c8 = 4) AND (r5c1 = 2) AND (r5c7 = 7) AND (r5c9 = 5) AND (r6c1 = 4) AND (r6c2 = 8) AND (r6c3 = 5) AND (r6c6 = 1) AND (r6c8 = 2) AND (r7c1 = 7) AND (r7c4 = 3) AND (r7c6 = 4) AND (r8c9 = 2) AND (r9c1 = 8) AND (r9c2 = 5) AND (r9c6 = 6) AND (r9c7 = 4) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 5) AND (r1c9 = 3) AND (r2c3 = 6) AND (r2c6 = 1) AND (r2c8 = 8) AND (r3c4 = 4) AND (r3c7 = 6) AND (r3c9 = 2) AND (r4c9 = 1) AND (r5c4 = 9) AND (r5c6 = 8) AND (r5c7 = 5) AND (r6c5 = 3) AND (r6c6 = 6) AND (r6c7 = 8) AND (r7c1 = 4) AND (r7c7 = 1) AND (r7c8 = 9) AND (r8c1 = 8) AND (r8c3 = 5) AND (r8c5 = 1) AND (r8c8 = 4) AND (r9c4 = 6) AND (r9c6 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c5 = 3) AND (r2c3 = 6) AND (r2c4 = 2) AND (r2c6 = 8) AND (r3c4 = 9) AND (r3c5 = 7) AND (r3c9 = 5) AND (r5c1 = 2) AND (r5c3 = 9) AND (r5c4 = 8) AND (r5c6 = 3) AND (r6c4 = 6) AND (r6c6 = 7) AND (r6c9 = 9) AND (r7c1 = 7) AND (r7c2 = 5) AND (r7c8 = 8) AND (r7c9 = 4) AND (r8c2 = 4) AND (r8c3 = 8) AND (r8c5 = 5) AND (r8c7 = 6) AND (r8c9 = 3) AND (r9c3 = 2) AND (r9c8 = 5) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 1) AND (r1c5 = 2) AND (r2c4 = 1) AND (r2c9 = 8) AND (r3c2 = 8) AND (r3c4 = 3) AND (r3c6 = 7) AND (r3c8 = 1) AND (r4c2 = 5) AND (r4c3 = 7) AND (r4c8 = 3) AND (r5c3 = 2) AND (r5c7 = 6) AND (r6c1 = 8) AND (r6c7 = 5) AND (r6c8 = 7) AND (r6c9 = 4) AND (r7c2 = 7) AND (r7c9 = 3) AND (r8c3 = 4) AND (r8c4 = 7) AND (r8c7 = 1) AND (r8c8 = 2) AND (r9c1 = 2) AND (r9c3 = 5) AND (r9c7 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c2 = 1) AND (r1c6 = 3) AND (r1c7 = 9) AND (r2c2 = 6) AND (r2c8 = 8) AND (r2c9 = 2) AND (r3c1 = 2) AND (r3c4 = 7) AND (r3c7 = 3) AND (r4c2 = 8) AND (r4c5 = 3) AND (r4c6 = 6) AND (r5c2 = 9) AND (r5c5 = 1) AND (r5c7 = 4) AND (r5c8 = 3) AND (r6c3 = 6) AND (r6c6 = 9) AND (r7c3 = 2) AND (r8c5 = 8) AND (r8c8 = 7) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c5 = 8) AND (r1c7 = 4) AND (r2c1 = 3) AND (r2c9 = 2) AND (r4c1 = 1) AND (r4c3 = 6) AND (r4c4 = 3) AND (r5c7 = 8) AND (r5c8 = 5) AND (r6c1 = 2) AND (r7c2 = 8) AND (r7c3 = 4) AND (r7c8 = 3) AND (r8c4 = 2) AND (r8c6 = 1) AND (r9c5 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 4) AND (r1c3 = 9) AND (r2c6 = 7) AND (r3c2 = 6) AND (r3c7 = 4) AND (r4c1 = 9) AND (r4c2 = 1) AND (r4c4 = 7) AND (r4c8 = 3) AND (r4c9 = 6) AND (r5c4 = 3) AND (r5c5 = 5) AND (r5c7 = 1) AND (r5c8 = 4) AND (r6c1 = 2) AND (r7c4 = 5) AND (r7c8 = 7) AND (r8c2 = 3) AND (r8c3 = 6) AND (r8c5 = 2) AND (r9c2 = 2) AND (r9c4 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c5 = 5) AND (r1c8 = 4) AND (r1c9 = 6) AND (r2c6 = 1) AND (r2c8 = 7) AND (r3c1 = 3) AND (r3c3 = 6) AND (r3c6 = 9) AND (r3c7 = 5) AND (r3c9 = 1) AND (r4c2 = 5) AND (r4c5 = 9) AND (r4c6 = 4) AND (r5c4 = 2) AND (r6c1 = 9) AND (r6c5 = 7) AND (r6c9 = 3) AND (r7c1 = 4) AND (r7c5 = 6) AND (r7c6 = 7) AND (r7c8 = 2) AND (r7c9 = 5) AND (r9c1 = 6) AND (r9c4 = 5) AND (r9c5 = 1) AND (r9c6 = 3) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c4 = 2) AND (r1c6 = 4) AND (r1c8 = 1) AND (r2c1 = 4) AND (r2c2 = 9) AND (r2c4 = 1) AND (r2c6 = 7) AND (r2c8 = 5) AND (r2c9 = 2) AND (r3c5 = 5) AND (r4c1 = 1) AND (r4c2 = 3) AND (r4c8 = 9) AND (r4c9 = 7) AND (r5c3 = 9) AND (r5c7 = 2) AND (r6c1 = 5) AND (r6c2 = 4) AND (r6c8 = 6) AND (r6c9 = 3) AND (r7c5 = 2) AND (r8c1 = 2) AND (r8c2 = 5) AND (r8c4 = 7) AND (r8c6 = 1) AND (r8c8 = 8) AND (r8c9 = 6) AND (r9c2 = 1) AND (r9c4 = 6) AND (r9c6 = 3) AND (r9c8 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 5) AND (r1c6 = 2) AND (r1c9 = 4) AND (r2c1 = 7) AND (r2c3 = 2) AND (r2c6 = 4) AND (r2c7 = 3) AND (r2c8 = 5) AND (r3c2 = 1) AND (r3c6 = 3) AND (r3c7 = 9) AND (r4c1 = 3) AND (r4c3 = 7) AND (r4c4 = 5) AND (r4c6 = 8) AND (r4c7 = 2) AND (r6c7 = 7) AND (r6c9 = 8) AND (r7c2 = 7) AND (r7c3 = 1) AND (r7c5 = 8) AND (r7c6 = 5) AND (r7c7 = 4) AND (r8c1 = 4) AND (r8c3 = 3) AND (r8c9 = 2) AND (r9c1 = 2) AND (r9c3 = 8) AND (r9c5 = 3) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c8 = 1) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 2) AND (r3c5 = 5) AND (r4c4 = 4) AND (r4c8 = 6) AND (r5c3 = 7) AND (r5c7 = 8) AND (r6c2 = 5) AND (r7c5 = 7) AND (r7c7 = 5) AND (r8c1 = 9) AND (r8c2 = 4) AND (r8c4 = 1) AND (r9c2 = 6) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c9 = 1) AND (r2c6 = 4) AND (r2c8 = 8) AND (r3c2 = 4) AND (r3c4 = 6) AND (r3c6 = 1) AND (r3c8 = 2) AND (r4c1 = 5) AND (r4c2 = 6) AND (r4c3 = 2) AND (r4c5 = 7) AND (r4c7 = 3) AND (r4c8 = 4) AND (r5c1 = 1) AND (r5c3 = 7) AND (r5c6 = 3) AND (r5c9 = 2) AND (r6c1 = 4) AND (r6c2 = 3) AND (r6c5 = 6) AND (r6c8 = 7) AND (r7c9 = 7) AND (r8c6 = 6) AND (r8c7 = 8) AND (r8c9 = 4) AND (r9c1 = 3) AND (r9c4 = 8) AND (r9c6 = 7) AND (r9c7 = 2) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 3) AND (r2c1 = 7) AND (r2c7 = 8) AND (r2c8 = 5) AND (r3c2 = 8) AND (r3c4 = 4) AND (r3c5 = 9) AND (r3c8 = 7) AND (r4c3 = 4) AND (r5c2 = 3) AND (r5c4 = 1) AND (r5c5 = 8) AND (r6c1 = 6) AND (r6c3 = 9) AND (r6c9 = 4) AND (r8c3 = 6) AND (r8c5 = 5) AND (r8c9 = 3) AND (r9c5 = 6) AND (r9c9 = 1);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c6 = 4) AND (r1c8 = 8) AND (r1c9 = 6) AND (r2c3 = 6) AND (r2c4 = 3) AND (r2c7 = 7) AND (r3c2 = 4) AND (r3c3 = 8) AND (r3c8 = 3) AND (r3c9 = 5) AND (r4c2 = 9) AND (r4c4 = 4) AND (r5c3 = 1) AND (r6c1 = 4) AND (r6c3 = 5) AND (r6c4 = 9) AND (r6c6 = 6) AND (r7c1 = 7) AND (r7c2 = 8) AND (r7c3 = 4) AND (r7c5 = 6) AND (r7c6 = 9) AND (r7c9 = 3) AND (r8c6 = 3) AND (r9c1 = 6) AND (r9c4 = 1) AND (r9c5 = 4) AND (r9c6 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 5) AND (r1c4 = 9) AND (r1c7 = 1) AND (r2c4 = 4) AND (r2c7 = 9) AND (r3c1 = 6) AND (r3c2 = 3) AND (r3c5 = 2) AND (r3c7 = 5) AND (r4c1 = 4) AND (r4c9 = 6) AND (r5c3 = 1) AND (r5c5 = 3) AND (r6c8 = 3) AND (r6c9 = 4) AND (r7c1 = 7) AND (r7c2 = 2) AND (r7c4 = 6) AND (r8c4 = 7) AND (r9c8 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 2) AND (r1c5 = 1) AND (r1c7 = 4) AND (r2c3 = 3) AND (r2c5 = 9) AND (r2c7 = 2) AND (r2c8 = 5) AND (r3c1 = 7) AND (r3c3 = 5) AND (r4c4 = 9) AND (r4c7 = 6) AND (r4c9 = 3) AND (r5c1 = 9) AND (r6c3 = 2) AND (r6c6 = 5) AND (r7c5 = 2) AND (r7c8 = 4) AND (r8c6 = 9) AND (r8c8 = 2) AND (r8c9 = 7) AND (r9c3 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 3) AND (r1c6 = 5) AND (r2c1 = 4) AND (r2c4 = 8) AND (r2c5 = 6) AND (r2c6 = 9) AND (r2c9 = 5) AND (r3c1 = 8) AND (r4c3 = 9) AND (r4c6 = 2) AND (r4c8 = 5) AND (r4c9 = 6) AND (r5c1 = 1) AND (r5c3 = 2) AND (r5c8 = 3) AND (r6c1 = 6) AND (r6c2 = 8) AND (r6c4 = 9) AND (r6c5 = 3) AND (r6c8 = 2) AND (r6c9 = 4) AND (r7c2 = 3) AND (r7c3 = 8) AND (r7c4 = 6) AND (r7c9 = 9) AND (r8c1 = 5) AND (r9c3 = 6) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c9 = 1) AND (r2c3 = 2) AND (r2c4 = 9) AND (r2c8 = 5) AND (r3c1 = 8) AND (r3c7 = 4) AND (r4c3 = 6) AND (r4c4 = 2) AND (r4c5 = 5) AND (r5c6 = 7) AND (r6c4 = 3) AND (r6c6 = 6) AND (r6c8 = 9) AND (r7c1 = 4) AND (r7c7 = 7) AND (r8c2 = 1) AND (r8c9 = 8) AND (r9c3 = 5) AND (r9c5 = 3) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 3) AND (r1c4 = 5) AND (r1c8 = 8) AND (r2c1 = 7) AND (r2c5 = 2) AND (r3c3 = 9) AND (r3c6 = 7) AND (r4c4 = 2) AND (r4c6 = 1) AND (r5c1 = 5) AND (r5c2 = 2) AND (r6c2 = 4) AND (r6c5 = 8) AND (r6c7 = 7) AND (r7c4 = 3) AND (r7c8 = 2) AND (r8c5 = 9) AND (r8c6 = 8) AND (r8c7 = 3) AND (r9c2 = 1) AND (r9c3 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c2 = 1) AND (r1c3 = 2) AND (r1c5 = 3) AND (r2c1 = 4) AND (r2c7 = 5) AND (r3c4 = 7) AND (r3c7 = 2) AND (r3c8 = 3) AND (r4c1 = 2) AND (r4c4 = 8) AND (r4c5 = 5) AND (r5c1 = 3) AND (r5c4 = 1) AND (r5c5 = 6) AND (r5c6 = 7) AND (r5c7 = 8) AND (r5c9 = 5) AND (r6c4 = 4) AND (r6c8 = 7) AND (r6c9 = 6) AND (r7c1 = 1) AND (r7c5 = 7) AND (r8c2 = 6) AND (r8c3 = 5) AND (r8c9 = 8) AND (r9c9 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c7 = 8) AND (r2c1 = 2) AND (r2c2 = 8) AND (r2c3 = 3) AND (r2c7 = 4) AND (r2c8 = 1) AND (r3c4 = 2) AND (r4c3 = 1) AND (r4c4 = 3) AND (r4c9 = 6) AND (r5c3 = 2) AND (r5c4 = 1) AND (r5c6 = 6) AND (r5c8 = 5) AND (r5c9 = 4) AND (r6c6 = 5) AND (r6c8 = 7) AND (r7c1 = 1) AND (r7c3 = 5) AND (r8c4 = 4) AND (r8c8 = 3) AND (r8c9 = 1) AND (r9c1 = 3) AND (r9c3 = 8) AND (r9c6 = 1) AND (r9c7 = 6) AND (r9c8 = 2) AND (r9c9 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c6 = 5) AND (r1c9 = 1) AND (r2c2 = 6) AND (r2c5 = 7) AND (r2c7 = 2) AND (r3c2 = 1) AND (r3c3 = 7) AND (r4c3 = 3) AND (r4c4 = 5) AND (r4c5 = 2) AND (r5c4 = 8) AND (r5c5 = 3) AND (r5c7 = 1) AND (r5c9 = 4) AND (r7c4 = 7) AND (r7c9 = 5) AND (r8c3 = 2) AND (r8c6 = 1) AND (r8c9 = 3) AND (r9c1 = 3) AND (r9c2 = 4) AND (r9c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 7) AND (r1c4 = 5) AND (r1c6 = 8) AND (r1c8 = 6) AND (r2c1 = 8) AND (r2c5 = 1) AND (r2c9 = 7) AND (r3c2 = 9) AND (r3c8 = 8) AND (r4c3 = 8) AND (r4c4 = 6) AND (r4c6 = 9) AND (r4c7 = 7) AND (r5c2 = 5) AND (r5c3 = 9) AND (r5c4 = 2) AND (r5c6 = 7) AND (r5c7 = 8) AND (r5c8 = 1) AND (r6c3 = 7) AND (r6c4 = 1) AND (r6c6 = 3) AND (r6c7 = 5) AND (r7c2 = 3) AND (r7c8 = 4) AND (r8c1 = 7) AND (r8c5 = 6) AND (r8c9 = 2) AND (r9c2 = 6) AND (r9c4 = 8) AND (r9c6 = 4) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 8) AND (r1c7 = 7) AND (r1c8 = 4) AND (r2c1 = 5) AND (r2c3 = 1) AND (r3c1 = 3) AND (r3c8 = 9) AND (r4c2 = 9) AND (r4c4 = 2) AND (r4c7 = 5) AND (r5c4 = 6) AND (r5c5 = 8) AND (r6c7 = 3) AND (r7c5 = 3) AND (r7c6 = 1) AND (r8c2 = 2) AND (r8c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 3) AND (r1c7 = 5) AND (r1c9 = 9) AND (r2c1 = 9) AND (r2c2 = 8) AND (r2c3 = 6) AND (r2c5 = 2) AND (r2c7 = 3) AND (r3c3 = 2) AND (r3c9 = 1) AND (r4c7 = 1) AND (r4c8 = 7) AND (r5c4 = 5) AND (r5c6 = 7) AND (r7c1 = 7) AND (r7c6 = 3) AND (r7c7 = 8) AND (r7c8 = 6) AND (r8c3 = 8) AND (r8c4 = 2) AND (r8c5 = 6) AND (r9c2 = 5) AND (r9c9 = 3);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 4) AND (r1c9 = 3) AND (r2c2 = 2) AND (r2c5 = 5) AND (r2c9 = 9) AND (r3c2 = 9) AND (r3c3 = 5) AND (r3c5 = 3) AND (r3c8 = 8) AND (r4c4 = 4) AND (r6c1 = 6) AND (r6c6 = 9) AND (r6c7 = 7) AND (r7c1 = 4) AND (r7c4 = 7) AND (r7c7 = 6) AND (r7c8 = 2) AND (r8c4 = 6) AND (r8c9 = 5) AND (r9c1 = 3) AND (r9c4 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 9) AND (r2c5 = 6) AND (r2c8 = 1) AND (r3c6 = 5) AND (r4c2 = 1) AND (r4c6 = 9) AND (r5c1 = 8) AND (r5c5 = 4) AND (r6c1 = 4) AND (r6c2 = 2) AND (r6c4 = 8) AND (r6c8 = 3) AND (r7c4 = 9) AND (r7c7 = 5) AND (r7c9 = 3) AND (r8c2 = 8) AND (r8c3 = 5) AND (r8c4 = 3) AND (r8c9 = 1) AND (r9c4 = 1) AND (r9c6 = 2) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c8 = 1) AND (r2c1 = 3) AND (r2c2 = 2) AND (r2c4 = 9) AND (r2c9 = 5) AND (r3c2 = 8) AND (r3c4 = 4) AND (r3c5 = 5) AND (r4c3 = 2) AND (r4c4 = 5) AND (r4c6 = 3) AND (r5c8 = 5) AND (r5c9 = 9) AND (r6c1 = 7) AND (r6c9 = 3) AND (r7c3 = 7) AND (r8c1 = 5) AND (r8c5 = 4) AND (r8c7 = 1) AND (r9c2 = 9) AND (r9c3 = 1) AND (r9c4 = 3) AND (r9c7 = 5) AND (r9c8 = 2) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c4 = 5) AND (r1c8 = 4) AND (r2c1 = 5) AND (r2c4 = 3) AND (r2c6 = 8) AND (r3c1 = 2) AND (r3c7 = 9) AND (r4c2 = 6) AND (r4c5 = 7) AND (r5c1 = 4) AND (r5c2 = 3) AND (r5c7 = 6) AND (r6c3 = 5) AND (r6c5 = 8) AND (r7c3 = 9) AND (r7c9 = 6) AND (r8c1 = 7) AND (r8c7 = 5) AND (r9c2 = 8) AND (r9c4 = 4) AND (r9c6 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 9) AND (r1c4 = 3) AND (r1c6 = 5) AND (r1c7 = 7) AND (r2c2 = 3) AND (r2c4 = 8) AND (r2c9 = 2) AND (r3c3 = 8) AND (r3c5 = 2) AND (r3c7 = 6) AND (r4c3 = 2) AND (r4c8 = 9) AND (r4c9 = 7) AND (r5c2 = 7) AND (r5c3 = 6) AND (r5c5 = 5) AND (r5c7 = 1) AND (r6c2 = 8) AND (r6c7 = 3) AND (r7c4 = 9) AND (r7c9 = 1) AND (r8c6 = 1) AND (r9c8 = 6);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 1) AND (r1c6 = 6) AND (r1c9 = 7) AND (r2c2 = 2) AND (r2c4 = 5) AND (r2c7 = 8) AND (r3c3 = 9) AND (r3c4 = 7) AND (r3c9 = 6) AND (r4c1 = 7) AND (r4c3 = 5) AND (r5c3 = 1) AND (r5c5 = 3) AND (r5c7 = 2) AND (r5c8 = 9) AND (r7c5 = 9) AND (r7c6 = 5) AND (r8c1 = 2) AND (r8c9 = 3) AND (r9c1 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 2) AND (r1c2 = 9) AND (r1c4 = 1) AND (r1c5 = 4) AND (r2c5 = 5) AND (r2c6 = 8) AND (r3c1 = 1) AND (r3c2 = 8) AND (r3c5 = 6) AND (r3c7 = 5) AND (r4c1 = 8) AND (r4c9 = 2) AND (r5c2 = 1) AND (r5c4 = 7) AND (r5c9 = 6) AND (r6c7 = 7) AND (r6c8 = 9) AND (r7c1 = 4) AND (r7c7 = 2) AND (r7c8 = 1) AND (r8c9 = 9) AND (r9c1 = 7) AND (r9c4 = 2) AND (r9c7 = 4) AND (r9c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 6) AND (r1c3 = 1) AND (r1c5 = 9) AND (r3c1 = 9) AND (r3c3 = 7) AND (r3c5 = 4) AND (r3c8 = 6) AND (r4c3 = 8) AND (r4c8 = 4) AND (r5c1 = 7) AND (r5c2 = 3) AND (r5c3 = 2) AND (r5c8 = 9) AND (r6c1 = 1) AND (r6c8 = 7) AND (r7c2 = 8) AND (r7c3 = 4) AND (r7c4 = 6) AND (r7c5 = 1) AND (r7c9 = 9) AND (r8c1 = 2) AND (r8c3 = 9) AND (r8c5 = 8) AND (r8c6 = 4) AND (r8c7 = 3) AND (r9c5 = 2) AND (r9c6 = 7) AND (r9c8 = 8) AND (r9c9 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 4) AND (r1c6 = 1) AND (r1c8 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 5) AND (r3c5 = 6) AND (r4c4 = 3) AND (r4c9 = 7) AND (r5c3 = 1) AND (r5c7 = 6) AND (r6c1 = 6) AND (r6c6 = 2) AND (r7c5 = 4) AND (r7c7 = 1) AND (r8c1 = 9) AND (r8c2 = 7) AND (r9c2 = 3) AND (r9c4 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c2 = 9) AND (r2c1 = 3) AND (r2c3 = 6) AND (r2c5 = 4) AND (r3c2 = 1) AND (r3c3 = 4) AND (r4c2 = 7) AND (r4c9 = 1) AND (r5c3 = 1) AND (r5c5 = 6) AND (r6c1 = 2) AND (r6c6 = 7) AND (r6c7 = 9) AND (r6c9 = 8) AND (r7c1 = 7) AND (r7c4 = 6) AND (r7c5 = 2) AND (r7c6 = 1) AND (r7c7 = 8) AND (r7c9 = 3) AND (r8c4 = 7) AND (r8c6 = 3) AND (r8c7 = 4) AND (r8c8 = 9) AND (r9c2 = 3) AND (r9c5 = 8) AND (r9c6 = 9) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 4) AND (r2c2 = 4) AND (r2c5 = 7) AND (r2c8 = 3) AND (r2c9 = 6) AND (r3c1 = 2) AND (r3c5 = 3) AND (r3c6 = 6) AND (r3c8 = 8) AND (r4c4 = 1) AND (r4c5 = 4) AND (r4c9 = 7) AND (r5c1 = 1) AND (r5c6 = 3) AND (r5c8 = 6) AND (r6c4 = 6) AND (r6c8 = 2) AND (r7c1 = 3) AND (r7c5 = 5) AND (r7c8 = 1) AND (r8c2 = 5) AND (r8c4 = 7) AND (r8c5 = 8) AND (r8c6 = 2) AND (r9c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c8 = 1) AND (r2c6 = 2) AND (r2c8 = 3) AND (r2c9 = 4) AND (r3c3 = 5) AND (r3c5 = 6) AND (r4c4 = 4) AND (r4c8 = 7) AND (r5c3 = 2) AND (r5c7 = 6) AND (r6c2 = 1) AND (r6c6 = 5) AND (r7c5 = 8) AND (r7c7 = 2) AND (r8c1 = 7) AND (r8c2 = 3) AND (r8c4 = 1) AND (r9c2 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 8) AND (r1c4 = 4) AND (r1c5 = 3) AND (r1c7 = 9) AND (r1c8 = 1) AND (r2c1 = 3) AND (r2c5 = 9) AND (r3c2 = 4) AND (r3c4 = 7) AND (r3c6 = 1) AND (r3c9 = 6) AND (r4c2 = 7) AND (r4c4 = 1) AND (r4c5 = 4) AND (r4c7 = 5) AND (r5c1 = 6) AND (r5c3 = 3) AND (r6c1 = 5) AND (r6c2 = 1) AND (r6c8 = 8) AND (r7c1 = 7) AND (r7c3 = 6) AND (r7c4 = 8) AND (r7c8 = 9) AND (r8c2 = 3) AND (r8c4 = 9) AND (r9c2 = 9) AND (r9c4 = 3) AND (r9c9 = 8);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 7) AND (r1c3 = 1) AND (r1c4 = 2) AND (r1c5 = 5) AND (r1c8 = 8) AND (r2c1 = 8) AND (r2c3 = 6) AND (r2c5 = 7) AND (r2c6 = 4) AND (r2c9 = 5) AND (r3c2 = 9) AND (r3c3 = 4) AND (r3c6 = 6) AND (r3c7 = 7) AND (r5c3 = 8) AND (r5c4 = 6) AND (r5c6 = 5) AND (r5c9 = 9) AND (r6c4 = 8) AND (r6c5 = 2) AND (r6c6 = 1) AND (r6c8 = 4) AND (r6c9 = 6) AND (r7c1 = 6) AND (r7c6 = 8) AND (r7c9 = 1) AND (r8c1 = 1) AND (r8c3 = 9) AND (r8c9 = 7) AND (r9c2 = 4);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 1) AND (r1c5 = 5) AND (r1c7 = 6) AND (r2c1 = 8) AND (r2c3 = 7) AND (r3c1 = 3) AND (r4c4 = 7) AND (r4c6 = 8) AND (r4c8 = 3) AND (r5c2 = 1) AND (r5c7 = 4) AND (r7c2 = 4) AND (r7c5 = 6) AND (r7c7 = 2) AND (r8c1 = 5) AND (r8c8 = 8) AND (r9c4 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 7) AND (r1c5 = 9) AND (r1c7 = 2) AND (r2c3 = 6) AND (r2c7 = 3) AND (r2c9 = 8) AND (r3c2 = 5) AND (r3c5 = 8) AND (r3c6 = 3) AND (r3c8 = 7) AND (r3c9 = 9) AND (r4c3 = 4) AND (r4c4 = 3) AND (r4c7 = 7) AND (r4c8 = 6) AND (r5c7 = 8) AND (r5c9 = 2) AND (r6c1 = 5) AND (r6c2 = 6) AND (r8c2 = 8) AND (r8c3 = 9) AND (r8c4 = 5) AND (r8c6 = 6) AND (r9c1 = 3) AND (r9c2 = 2) AND (r9c9 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c3 = 2) AND (r1c4 = 8) AND (r1c6 = 1) AND (r1c7 = 5) AND (r1c8 = 4) AND (r2c5 = 3) AND (r3c4 = 4) AND (r3c5 = 6) AND (r3c6 = 5) AND (r4c1 = 8) AND (r4c3 = 3) AND (r4c6 = 9) AND (r4c7 = 4) AND (r4c9 = 5) AND (r5c2 = 5) AND (r5c6 = 3) AND (r5c9 = 1) AND (r6c3 = 6) AND (r6c7 = 3) AND (r7c4 = 2) AND (r7c6 = 4) AND (r8c3 = 5) AND (r8c5 = 1) AND (r8c6 = 8) AND (r8c7 = 6) AND (r8c8 = 2) AND (r9c3 = 9) AND (r9c5 = 5);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c4 = 1) AND (r2c1 = 1) AND (r2c2 = 2) AND (r2c5 = 9) AND (r2c8 = 7) AND (r3c5 = 7) AND (r3c6 = 6) AND (r5c2 = 6) AND (r5c5 = 3) AND (r5c6 = 9) AND (r5c8 = 1) AND (r6c1 = 5) AND (r6c3 = 9) AND (r6c4 = 4) AND (r6c6 = 7) AND (r6c8 = 2) AND (r7c3 = 2) AND (r7c6 = 3) AND (r7c7 = 4) AND (r7c8 = 5) AND (r8c1 = 6) AND (r8c4 = 7) AND (r8c5 = 2) AND (r8c8 = 3) AND (r8c9 = 9) AND (r9c2 = 7) AND (r9c4 = 9) AND (r9c5 = 4) AND (r9c6 = 1) AND (r9c8 = 6) AND (r9c9 = 2);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 2) AND (r2c3 = 5) AND (r2c5 = 3) AND (r2c6 = 9) AND (r2c7 = 8) AND (r3c1 = 8) AND (r3c2 = 4) AND (r3c3 = 9) AND (r3c5 = 7) AND (r4c3 = 7) AND (r4c4 = 3) AND (r4c5 = 2) AND (r4c6 = 6) AND (r5c4 = 7) AND (r5c5 = 4) AND (r5c6 = 8) AND (r5c9 = 3) AND (r6c6 = 5) AND (r7c3 = 3) AND (r7c5 = 6) AND (r7c9 = 5) AND (r8c2 = 5) AND (r8c4 = 9) AND (r8c8 = 6) AND (r9c1 = 4) AND (r9c3 = 8) AND (r9c5 = 5) AND (r9c6 = 7) AND (r9c8 = 3) AND (r9c9 = 9);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 1) AND (r1c2 = 9) AND (r2c1 = 8) AND (r2c5 = 7) AND (r2c8 = 1) AND (r2c9 = 6) AND (r3c2 = 7) AND (r3c4 = 2) AND (r3c7 = 5) AND (r3c9 = 3) AND (r4c8 = 2) AND (r4c9 = 7) AND (r5c2 = 3) AND (r5c9 = 8) AND (r6c1 = 9) AND (r6c3 = 5) AND (r7c2 = 1) AND (r7c3 = 8) AND (r7c6 = 2) AND (r7c8 = 3) AND (r8c9 = 2) AND (r9c2 = 6) AND (r9c5 = 1) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c1 = 8) AND (r1c3 = 5) AND (r1c9 = 2) AND (r2c4 = 9) AND (r2c6 = 1) AND (r3c1 = 3) AND (r4c2 = 6) AND (r4c4 = 7) AND (r4c7 = 4) AND (r5c1 = 2) AND (r5c5 = 5) AND (r6c8 = 6) AND (r7c4 = 3) AND (r7c5 = 8) AND (r8c2 = 1) AND (r8c7 = 9) AND (r9c2 = 4) AND (r9c8 = 7);
SELECT * FROM sudoku_memory_combined_view WHERE (r1c2 = 8) AND (r2c1 = 1) AND (r2c3 = 7) AND (r2c7 = 8) AND (r2c9 = 3) AND (r3c6 = 6) AND (r3c9 = 1) AND (r4c2 = 2) AND (r5c1 = 3) AND (r5c5 = 1) AND (r6c3 = 8) AND (r6c4 = 5) AND (r6c7 = 6) AND (r6c8 = 9) AND (r7c5 = 3) AND (r7c6 = 7) AND (r7c7 = 9) AND (r8c6 = 1) AND (r9c1 = 5) AND (r9c2 = 9);
UPDATE tests SET fin = NOW() WHERE fin IS NULL;
SELECT TO_SECONDS(fin) - TO_SECONDS(debut) FROM tests;
```

6. Gosser à la main!

Maintenant que nous avons un échantillon représentatif et significatif et tout ce qu’il nous faut pour mesurer, de façon répétable et facile, chacun des changements que nous voulons effectuer, nous sommes en mesure de vérifier l’impact de 2 variables importantes : optimizer_search_depth et join_buffer_size.

Tout d’abord, la variable optimizer_search_depth dont voici les différents résultats :

Il est clair que cette variable a un impact majeur.  Nous savons maintenant que la valeur optimale de cette variable (dans notre cas précis) est 1.

On serait tenté de croire que la variable join_buffer_size pourrait avoir un impact non négligeable mais ce n’est pas le cas ici.

Les différences de temps (hormis pour la valeur 2Mb) ne sont pas assez significatives pour indiquer une tendance.  Malgré tout, théoriquement, cette variable devrait avoir un impact.  Pour les biens de la cause, autant avoir plus de mémoire que moins pour cette variable!  Je vous recommande donc 128Mb (plus, dans notre cas, serait un gaspillage de mémoire).

Finalement, pour mettre en valeur la différence entre une solution utilisant une table sur disque versus notre solution finale (une table en mémoire), l’histogramme suivant parle de lui-même!

Voilà!  CQFD. En espérant que cette série d’articles vous aura permis de constater que parfois, il est nécessaire de penser out of the box et d’envisager des solutions saugrenues pour arriver à ses fins.

7. Ressources et outils

Quelques-unes des ressources et des outils utilisés dans le cadre de cette série d’articles:

setbb.com : des forums de discussion sur le sudoku (en anglais) pour les programmeurs

enjoysudoku.com : des forums de discussions (en anglais) variés et nombreux sur les sudokus

QQWing : un outil (en ligne de commande) permettant de solutionner et de générer des grilles de sudoku

SudoCue : une application permettant de solutionner et générer des sudokus

Sudoku Explainer : une application permettant de solutionner et générer des sudokus

R : langage de programmation et environnement mathématique utilisé pour le traitement de données et l’analyse statistique

db4free.net : un serveur MySQL vous permettant de créer une base de donnée gratuitement et d’expérimenter

Pharo : un environnement de développement Smalltalk

## Comment presser un citron (deuxième partie)

8 janvier 2012

Dans le premier article, nous avons vu combien il était facile de solutionner des grilles de sudoku avec une seule requête SQL. Malheureusement, c’était trop beau pour être vrai…

Avant de poursuivre, voici un outil utile pour se faciliter la tâche.  Pour ceux qui utilisent Smalltalk, vous pouvez vous aider du script suivant :

```
| uneTableOuVue uneStringSudoku stream estLePremier |

uneTableOuVue := 'sudoku_rows_view'.
uneStringSudoku := '.........134825697759364182397182564.........581476239825641973976538421.........'.

stream := ReadWriteStream on: String new.
stream
nextPutAll: 'SELECT * '; cr;
nextPutAll: 'FROM ';
nextPutAll: uneTableOuVue;
space; cr;
nextPutAll: 'WHERE'; cr.

estLePremier := false.
1 to: 9 do: [:r |
1 to: 9 do: [:c | | i |
i := (r-1)*9 + c.
((uneStringSudoku at: i) ~= \$. and: [(uneStringSudoku at: i) ~= 0])
ifTrue: [    estLePremier ifTrue: [stream nextPutAll: ' AND ';cr].
estLePremier := true.
stream
nextPutAll: '(r'; nextPutAll: r asString;
nextPutAll: 'c'; nextPutAll: c asString;
nextPutAll: ' = ';
nextPutAll: (uneStringSudoku at: i) asString;
nextPutAll: ')'.
].]].
Transcript cr;show: stream contents

```

Ce script génère  les requêtes SQL à partir d’une chaîne de caractères (uneStringSudoku) représentant une grille de sudoku pour une table/vue précise (uneTableOuVue) en affichant le résultat dans le Transcript.

1. Problème majeur

Il y a une faille majeure et évidente dans la solution telle que présentée : elle repose totalement sur la capacité de MySQL de faire correspondre les révélés (givens en anglais) de la grille à des lignes. Que se passerait-il si une ligne (ou pire encore, plusieurs lignes) dans le sudoku ne contenait pas de révélés (ou pas assez)? Sans index à utiliser, une lecture séquentielle de la table nous attend sans doute! Prenons, par exemple, la grille suivante:

Ce sudoku contient 54 révélés (la première grille n’en comptait que 30, près de la moitié de celle-ci) et 6 de ses lignes seront rapidement récupérées avec les index.  De plus, il y a suffisamment de révélés pour éliminer rapidement un bon nombre de lignes candidates avec les contraintes du puzzle incluses dans la vue sudoku_rows_view.

Cependant les lignes vides (1, 5 et 9) causeront probablement une lecture séquentielle (table scan) de la table.  Nous faisons face à un problème majeur avec les lignes 1, 5 et 9 étant vides! Examinons la requête pour ce sudoku :

```EXPLAIN
SELECT *
FROM sudoku_rows_view
WHERE
(r2c1 = 1) AND (r2c2 = 3) AND (r2c3 = 4) AND (r2c4 = 8) AND
(r2c5 = 2) AND (r2c6 = 5) AND (r2c7 = 6) AND (r2c8 = 9) AND
(r2c9 = 7) AND (r3c1 = 7) AND (r3c2 = 5) AND (r3c3 = 9) AND
(r3c4 = 3) AND (r3c5 = 6) AND (r3c6 = 4) AND (r3c7 = 1) AND
(r3c8 = 8) AND (r3c9 = 2) AND (r4c1 = 3) AND (r4c2 = 9) AND
(r4c3 = 7) AND (r4c4 = 1) AND (r4c5 = 8) AND (r4c6 = 2) AND
(r4c7 = 5) AND (r4c8 = 6) AND (r4c9 = 4) AND (r6c1 = 5) AND
(r6c2 = 8) AND (r6c3 = 1) AND (r6c4 = 4) AND (r6c5 = 7) AND
(r6c6 = 6) AND (r6c7 = 2) AND (r6c8 = 3) AND (r6c9 = 9) AND
(r7c1 = 8) AND (r7c2 = 2) AND (r7c3 = 5) AND (r7c4 = 6) AND
(r7c5 = 4) AND (r7c6 = 1) AND (r7c7 = 9) AND (r7c8 = 7) AND
(r7c9 = 3) AND (r8c1 = 9) AND (r8c2 = 7) AND (r8c3 = 6) AND
(r8c4 = 5) AND (r8c5 = 3) AND (r8c6 = 8) AND (r8c7 = 4) AND
(r8c8 = 2) AND (r8c9 = 1);
```

Le résultat du EXPLAIN :

```+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+------+--------+----------------------------------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                                                                                                                      | key         | key_len | ref  | rows   | Extra                                                                            |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+------+--------+----------------------------------------------------------------------------------+
|  1 | SIMPLE      | r2    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i29     | 2,2     | NULL |     68 | Using intersect(i37,i29); Using where                                            |
|  1 | SIMPLE      | r3    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i28     | 2,2     | NULL |     68 | Using intersect(i37,i28); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r4    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i56,i29     | 2,2     | NULL |     68 | Using intersect(i56,i29); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r6    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12,i35     | 2,2     | NULL |     68 | Using intersect(i12,i35); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r7    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12,i68     | 2,2     | NULL |     68 | Using intersect(i12,i68); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r8    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i79,i38 | 2,2,2   | NULL |     78 | Using intersect(i37,i79,i38); Using where; Using join buffer (Block Nested Loop) |
|  1 | SIMPLE      | r1    | range       | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23         | 1       | NULL |  40012 | Using index condition; Using where; Using join buffer (Block Nested Loop)        |
|  1 | SIMPLE      | r5    | ALL         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | NULL        | NULL    | NULL | 362880 | Using where; Using join buffer (Block Nested Loop)                               |
|  1 | SIMPLE      | r9    | ALL         | NULL                                                                                                                                               | NULL        | NULL    | NULL | 362880 | Using where; Using join buffer (Block Nested Loop)                               |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+------+--------+----------------------------------------------------------------------------------+
9 rows in set (13.39 sec)
```

Les lignes vides (lignes 1, 5 et 9) nous feront payer très chèrement le fait que nous ne pouvons pas utiliser pleinement les index! Il n’y a qu’à constater le nombre de lignes à potentiellement examiner pour joindre les tables r1, r5 et r9 (40012 x 362880 x 362880 = 5268855958732800) ainsi que le type de jointure utilisé (range, ALL et ALL).

Vérifions en combien de temps la requête s’exécute :

```
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| r1c1 | r1c2 | r1c3 | r1c4 | r1c5 | r1c6 | r1c7 | r1c8 | r1c9 | r2c1 | r2c2 | r2c3 | r2c4 | r2c5 | r2c6 | r2c7 | r2c8 | r2c9 | r3c1 | r3c2 | r3c3 | r3c4 | r3c5 | r3c6 | r3c7 | r3c8 | r3c9 | r4c1 | r4c2 | r4c3 | r4c4 | r4c5 | r4c6 | r4c7 | r4c8 | r4c9 | r5c1 | r5c2 | r5c3 | r5c4 | r5c5 | r5c6 | r5c7 | r5c8 | r5c9 | r6c1 | r6c2 | r6c3 | r6c4 | r6c5 | r6c6 | r6c7 | r6c8 | r6c9 | r7c1 | r7c2 | r7c3 | r7c4 | r7c5 | r7c6 | r7c7 | r7c8 | r7c9 | r8c1 | r8c2 | r8c3 | r8c4 | r8c5 | r8c6 | r8c7 | r8c8 | r8c9 | r9c1 | r9c2 | r9c3 | r9c4 | r9c5 | r9c6 | r9c7 | r9c8 | r9c9 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|    2 |    6 |    8 |    7 |    1 |    9 |    3 |    4 |    5 |    1 |    3 |    4 |    8 |    2 |    5 |    6 |    9 |    7 |    7 |    5 |    9 |    3 |    6 |    4 |    1 |    8 |    2 |    3 |    9 |    7 |    1 |    8 |    2 |    5 |    6 |    4 |    6 |    4 |    2 |    9 |    5 |    3 |    7 |    1 |    8 |    5 |    8 |    1 |    4 |    7 |    6 |    2 |    3 |    9 |    8 |    2 |    5 |    6 |    4 |    1 |    9 |    7 |    3 |    9 |    7 |    6 |    5 |    3 |    8 |    4 |    2 |    1 |    4 |    1 |    3 |    2 |    9 |    7 |    8 |    5 |    6 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1 row in set (6.17 sec)

```

Ouf!  Nous sommes passés de 0.39 seconde (grille 01) à 6.17 secondes (grille 02) malgré le fait que la grille 02 comporte près de 2 fois plus de révélés que la grille 01!  Cet exemple démontre clairement que les choses peuvent rapidement mal tourner à un rythme alarmant (même exponentiel) quand nous sommes confrontés à une grille contenant des lignes vides ou presque vides!

2. Changer de point de vue!

Imaginons maintenant que nous faisons effectuer une rotation à notre grille et que les colonnes deviennent des lignes.  Dans ce cas, chaque nouvelle ligne pourrait dès lors bénéficier des index!

Voyons cette nouvelle grille :

La requête aurait désormais l’air de ceci :

```
SELECT *
FROM sudoku_rows_view
WHERE
(r1c2 = 1) AND (r1c3 = 7) AND (r1c4 = 3) AND (r1c6 = 5) AND
(r1c7 = 8) AND (r1c8 = 9) AND (r2c2 = 3) AND (r2c3 = 5) AND
(r2c4 = 9) AND (r2c6 = 8) AND (r2c7 = 2) AND (r2c8 = 7) AND
(r3c2 = 4) AND (r3c3 = 9) AND (r3c4 = 7) AND (r3c6 = 1) AND
(r3c7 = 5) AND (r3c8 = 6) AND (r4c2 = 8) AND (r4c3 = 3) AND
(r4c4 = 1) AND (r4c6 = 4) AND (r4c7 = 6) AND (r4c8 = 5) AND
(r5c2 = 2) AND (r5c3 = 6) AND (r5c4 = 8) AND (r5c6 = 7) AND
(r5c7 = 4) AND (r5c8 = 3) AND (r6c2 = 5) AND (r6c3 = 4) AND
(r6c4 = 2) AND (r6c6 = 6) AND (r6c7 = 1) AND (r6c8 = 8) AND
(r7c2 = 6) AND (r7c3 = 1) AND (r7c4 = 5) AND (r7c6 = 2) AND
(r7c7 = 9) AND (r7c8 = 4) AND (r8c2 = 9) AND (r8c3 = 8) AND
(r8c4 = 6) AND (r8c6 = 3) AND (r8c7 = 7) AND (r8c8 = 2) AND
(r9c2 = 7) AND (r9c3 = 2) AND (r9c4 = 4) AND (r9c6 = 9) AND
(r9c7 = 3) AND (r9c8 = 1);
```

Le résultat du EXPLAIN correspondant :

```
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+------+------+----------------------------------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                                                                                                                      | key         | key_len | ref  | rows | Extra                                                                            |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+------+------+----------------------------------------------------------------------------------+
|  1 | SIMPLE      | r3    | index_merge | i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i67,i68,i69,i78,i79,i89                                                    | i23,i38,i48 | 2,2,2   | NULL |   64 | Using intersect(i23,i38,i48); Using where                                        |
|  1 | SIMPLE      | r9    | index_merge | i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i67,i68,i69,i78,i79,i89                                                    | i78,i68,i48 | 2,2,2   | NULL |   65 | Using intersect(i78,i68,i48); Using where; Using join buffer (Block Nested Loop) |
|  1 | SIMPLE      | r1    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i67     | 2,2     | NULL |   68 | Using intersect(i23,i67); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r2    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL |   68 | Using intersect(i23,i68); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r4    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i78,i46     | 2,2     | NULL |   68 | Using intersect(i78,i46); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r5    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL |   68 | Using intersect(i23,i68); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r6    | index_merge | i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i67,i68,i69,i78,i79,i89                                                    | i23,i67     | 2,2     | NULL |   68 | Using intersect(i23,i67); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r7    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL |   68 | Using intersect(i23,i68); Using where; Using join buffer (Block Nested Loop)     |
|  1 | SIMPLE      | r8    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i24     | 2,2     | NULL |   68 | Using intersect(i37,i24); Using where; Using join buffer (Block Nested Loop)     |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+------+------+----------------------------------------------------------------------------------+
9 rows in set (42.98 sec)

```

Et combien de temps la requête prendrait-elle à s’exécuter?

```SELECT *
FROM sudoku_rows_view
WHERE
(r1c2 = 1) AND (r1c3 = 7) AND (r1c4 = 3) AND (r1c6 = 5) AND
(r1c7 = 8) AND (r1c8 = 9) AND (r2c2 = 3) AND (r2c3 = 5) AND
(r2c4 = 9) AND (r2c6 = 8) AND (r2c7 = 2) AND (r2c8 = 7) AND
(r3c2 = 4) AND (r3c3 = 9) AND (r3c4 = 7) AND (r3c6 = 1) AND
(r3c7 = 5) AND (r3c8 = 6) AND (r4c2 = 8) AND (r4c3 = 3) AND
(r4c4 = 1) AND (r4c6 = 4) AND (r4c7 = 6) AND (r4c8 = 5) AND
(r5c2 = 2) AND (r5c3 = 6) AND (r5c4 = 8) AND (r5c6 = 7) AND
(r5c7 = 4) AND (r5c8 = 3) AND (r6c2 = 5) AND (r6c3 = 4) AND
(r6c4 = 2) AND (r6c6 = 6) AND (r6c7 = 1) AND (r6c8 = 8) AND
(r7c2 = 6) AND (r7c3 = 1) AND (r7c4 = 5) AND (r7c6 = 2) AND
(r7c7 = 9) AND (r7c8 = 4) AND (r8c2 = 9) AND (r8c3 = 8) AND
(r8c4 = 6) AND (r8c6 = 3) AND (r8c7 = 7) AND (r8c8 = 2) AND
(r9c2 = 7) AND (r9c3 = 2) AND (r9c4 = 4) AND (r9c6 = 9) AND
(r9c7 = 3) AND (r9c8 = 1);
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| r1c1 | r1c2 | r1c3 | r1c4 | r1c5 | r1c6 | r1c7 | r1c8 | r1c9 | r2c1 | r2c2 | r2c3 | r2c4 | r2c5 | r2c6 | r2c7 | r2c8 | r2c9 | r3c1 | r3c2 | r3c3 | r3c4 | r3c5 | r3c6 | r3c7 | r3c8 | r3c9 | r4c1 | r4c2 | r4c3 | r4c4 | r4c5 | r4c6 | r4c7 | r4c8 | r4c9 | r5c1 | r5c2 | r5c3 | r5c4 | r5c5 | r5c6 | r5c7 | r5c8 | r5c9 | r6c1 | r6c2 | r6c3 | r6c4 | r6c5 | r6c6 | r6c7 | r6c8 | r6c9 | r7c1 | r7c2 | r7c3 | r7c4 | r7c5 | r7c6 | r7c7 | r7c8 | r7c9 | r8c1 | r8c2 | r8c3 | r8c4 | r8c5 | r8c6 | r8c7 | r8c8 | r8c9 | r9c1 | r9c2 | r9c3 | r9c4 | r9c5 | r9c6 | r9c7 | r9c8 | r9c9 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
|    2 |    1 |    7 |    3 |    6 |    5 |    8 |    9 |    4 |    6 |    3 |    5 |    9 |    4 |    8 |    2 |    7 |    1 |    8 |    4 |    9 |    7 |    2 |    1 |    5 |    6 |    3 |    7 |    8 |    3 |    1 |    9 |    4 |    6 |    5 |    2 |    1 |    2 |    6 |    8 |    5 |    7 |    4 |    3 |    9 |    9 |    5 |    4 |    2 |    3 |    6 |    1 |    8 |    7 |    3 |    6 |    1 |    5 |    7 |    2 |    9 |    4 |    8 |    4 |    9 |    8 |    6 |    1 |    3 |    7 |    2 |    5 |    5 |    7 |    2 |    4 |    8 |    9 |    3 |    1 |    6 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
1 row in set (0.22 sec)
```

Nous sommes passés de 6.17 secondes à 0.22 seconde! Un gain imposant!

3. Les vues combinées

Alors pourquoi ne tenterions-nous pas de résoudre nos sudokus en effectuant la recherche par ligne ET par colonne à la fois?

Nous allons donc construire une seconde vue (sudoku_columns_view) qui sera basée sur les colonnes de la grille.  Pour faire résoudre les sudokus, il nous faudra une troisième vue (sudoku_combined_view) qui combinera la vue par lignes (sudoku_rows_view) avec la vue par colonne (sudoku_columns_view).  De cette façon, nous serons à l’abri des grilles avec des lignes vides et des grilles avec des colonnes vides.  L’optimisateur de requête aura dorénavant tout le luxe de choisir la « méthode » la plus efficace!

Construisons la vue par colonnes en exécutant cette requête :

```USE sudoku;

CREATE VIEW sudoku_columns_view AS
SELECT
col1.c1 as r1c1, col1.c2 as r2c1, col1.c3 as r3c1, col1.c4 as r4c1, col1.c5 as r5c1,col1.c6 as r6c1, col1.c7 as r7c1, col1.c8 as r8c1, col1.c9 as r9c1, col2.c1 as r1c2,
col2.c2 as r2c2, col2.c3 as r3c2, col2.c4 as r4c2, col2.c5 as r5c2, col2.c6 as r6c2,col2.c7 as r7c2, col2.c8 as r8c2, col2.c9 as r9c2, col3.c1 as r1c3, col3.c2 as r2c3,
col3.c3 as r3c3, col3.c4 as r4c3, col3.c5 as r5c3, col3.c6 as r6c3, col3.c7 as r7c3,col3.c8 as r8c3, col3.c9 as r9c3, col4.c1 as r1c4, col4.c2 as r2c4, col4.c3 as r3c4,
col4.c4 as r4c4, col4.c5 as r5c4, col4.c6 as r6c4, col4.c7 as r7c4, col4.c8 as r8c4,col4.c9 as r9c4, col5.c1 as r1c5, col5.c2 as r2c5, col5.c3 as r3c5, col5.c4 as r4c5,
col5.c5 as r5c5, col5.c6 as r6c5, col5.c7 as r7c5, col5.c8 as r8c5, col5.c9 as r9c5,col6.c1 as r1c6, col6.c2 as r2c6, col6.c3 as r3c6, col6.c4 as r4c6, col6.c5 as r5c6,
col6.c6 as r6c6, col6.c7 as r7c6, col6.c8 as r8c6, col6.c9 as r9c6, col7.c1 as r1c7,col7.c2 as r2c7, col7.c3 as r3c7, col7.c4 as r4c7, col7.c5 as r5c7, col7.c6 as r6c7,
col7.c7 as r7c7, col7.c8 as r8c7, col7.c9 as r9c7, col8.c1 as r1c8, col8.c2 as r2c8,col8.c3 as r3c8, col8.c4 as r4c8, col8.c5 as r5c8, col8.c6 as r6c8, col8.c7 as r7c8,
col8.c8 as r8c8, col8.c9 as r9c8, col9.c1 as r1c9, col9.c2 as r2c9, col9.c3 as r3c9,col9.c4 as r4c9, col9.c5 as r5c9, col9.c6 as r6c9, col9.c7 as r7c9, col9.c8 as r8c9,
col9.c9 as r9c9
FROM
positions col1, positions col2, positions col3,positions col4, positions col5, positions col6,positions col7, positions col8, positions col9
WHERE
-- Nombres uniques dans chaque rangee
(col1.c1 <> col2.c1) AND (col1.c1 <> col3.c1) AND (col1.c1 <> col4.c1) AND (col1.c1 <> col5.c1) AND (col1.c1 <> col6.c1) AND (col1.c1 <> col7.c1) AND (col1.c1 <> col8.c1) AND (col1.c1 <> col9.c1) AND (col1.c2 <> col2.c2) AND (col1.c2 <> col3.c2) AND (col1.c2 <> col4.c2) AND (col1.c2 <> col5.c2) AND (col1.c2 <> col6.c2) AND (col1.c2 <> col7.c2) AND (col1.c2 <> col8.c2) AND (col1.c2 <> col9.c2) AND (col1.c3 <> col2.c3) AND (col1.c3 <> col3.c3) AND (col1.c3 <> col4.c3) AND (col1.c3 <> col5.c3) AND (col1.c3 <> col6.c3) AND (col1.c3 <> col7.c3) AND (col1.c3 <> col8.c3) AND (col1.c3 <> col9.c3) AND (col1.c4 <> col2.c4) AND (col1.c4 <> col3.c4) AND (col1.c4 <> col4.c4) AND (col1.c4 <> col5.c4) AND (col1.c4 <> col6.c4) AND (col1.c4 <> col7.c4) AND (col1.c4 <> col8.c4) AND (col1.c4 <> col9.c4) AND
(col1.c5 <> col2.c5) AND (col1.c5 <> col3.c5) AND (col1.c5 <> col4.c5) AND (col1.c5 <> col5.c5) AND (col1.c5 <> col6.c5) AND (col1.c5 <> col7.c5) AND (col1.c5 <> col8.c5) AND (col1.c5 <> col9.c5) AND (col1.c6 <> col2.c6) AND (col1.c6 <> col3.c6) AND (col1.c6 <> col4.c6) AND (col1.c6 <> col5.c6) AND (col1.c6 <> col6.c6) AND (col1.c6 <> col7.c6) AND (col1.c6 <> col8.c6) AND (col1.c6 <> col9.c6) AND (col1.c7 <> col2.c7) AND (col1.c7 <> col3.c7) AND (col1.c7 <> col4.c7) AND (col1.c7 <> col5.c7) AND (col1.c7 <> col6.c7) AND (col1.c7 <> col7.c7) AND (col1.c7 <> col8.c7) AND (col1.c7 <> col9.c7) AND (col1.c8 <> col2.c8) AND (col1.c8 <> col3.c8) AND (col1.c8 <> col4.c8) AND (col1.c8 <> col5.c8) AND (col1.c8 <> col6.c8) AND (col1.c8 <> col7.c8) AND (col1.c8 <> col8.c8) AND (col1.c8 <> col9.c8) AND
(col1.c9 <> col2.c9) AND (col1.c9 <> col3.c9) AND (col1.c9 <> col4.c9) AND (col1.c9 <> col5.c9) AND (col1.c9 <> col6.c9) AND (col1.c9 <> col7.c9) AND (col1.c9 <> col8.c9) AND (col1.c9 <> col9.c9) AND (col2.c1 <> col3.c1) AND (col2.c1 <> col4.c1) AND (col2.c1 <> col5.c1) AND (col2.c1 <> col6.c1) AND (col2.c1 <> col7.c1) AND (col2.c1 <> col8.c1) AND (col2.c1 <> col9.c1) AND (col2.c2 <> col3.c2) AND (col2.c2 <> col4.c2) AND (col2.c2 <> col5.c2) AND (col2.c2 <> col6.c2) AND (col2.c2 <> col7.c2) AND (col2.c2 <> col8.c2) AND (col2.c2 <> col9.c2) AND (col2.c3 <> col3.c3) AND (col2.c3 <> col4.c3) AND (col2.c3 <> col5.c3) AND (col2.c3 <> col6.c3) AND (col2.c3 <> col7.c3) AND (col2.c3 <> col8.c3) AND (col2.c3 <> col9.c3) AND (col2.c4 <> col3.c4) AND (col2.c4 <> col4.c4) AND (col2.c4 <> col5.c4) AND
(col2.c4 <> col6.c4) AND (col2.c4 <> col7.c4) AND (col2.c4 <> col8.c4) AND (col2.c4 <> col9.c4) AND (col2.c5 <> col3.c5) AND (col2.c5 <> col4.c5) AND (col2.c5 <> col5.c5) AND (col2.c5 <> col6.c5) AND (col2.c5 <> col7.c5) AND (col2.c5 <> col8.c5) AND (col2.c5 <> col9.c5) AND (col2.c6 <> col3.c6) AND (col2.c6 <> col4.c6) AND (col2.c6 <> col5.c6) AND (col2.c6 <> col6.c6) AND (col2.c6 <> col7.c6) AND (col2.c6 <> col8.c6) AND (col2.c6 <> col9.c6) AND (col2.c7 <> col3.c7) AND (col2.c7 <> col4.c7) AND (col2.c7 <> col5.c7) AND (col2.c7 <> col6.c7) AND (col2.c7 <> col7.c7) AND (col2.c7 <> col8.c7) AND (col2.c7 <> col9.c7) AND (col2.c8 <> col3.c8) AND (col2.c8 <> col4.c8) AND (col2.c8 <> col5.c8) AND (col2.c8 <> col6.c8) AND (col2.c8 <> col7.c8) AND (col2.c8 <> col8.c8) AND (col2.c8 <> col9.c8) AND
(col2.c9 <> col3.c9) AND (col2.c9 <> col4.c9) AND (col2.c9 <> col5.c9) AND (col2.c9 <> col6.c9) AND (col2.c9 <> col7.c9) AND (col2.c9 <> col8.c9) AND (col2.c9 <> col9.c9) AND (col3.c1 <> col4.c1) AND (col3.c1 <> col5.c1) AND (col3.c1 <> col6.c1) AND (col3.c1 <> col7.c1) AND (col3.c1 <> col8.c1) AND (col3.c1 <> col9.c1) AND (col3.c2 <> col4.c2) AND (col3.c2 <> col5.c2) AND (col3.c2 <> col6.c2) AND (col3.c2 <> col7.c2) AND (col3.c2 <> col8.c2) AND (col3.c2 <> col9.c2) AND (col3.c3 <> col4.c3) AND (col3.c3 <> col5.c3) AND (col3.c3 <> col6.c3) AND (col3.c3 <> col7.c3) AND (col3.c3 <> col8.c3) AND (col3.c3 <> col9.c3) AND (col3.c4 <> col4.c4) AND (col3.c4 <> col5.c4) AND (col3.c4 <> col6.c4) AND (col3.c4 <> col7.c4) AND (col3.c4 <> col8.c4) AND (col3.c4 <> col9.c4) AND (col3.c5 <> col4.c5) AND
(col3.c5 <> col5.c5) AND (col3.c5 <> col6.c5) AND (col3.c5 <> col7.c5) AND (col3.c5 <> col8.c5) AND (col3.c5 <> col9.c5) AND (col3.c6 <> col4.c6) AND (col3.c6 <> col5.c6) AND (col3.c6 <> col6.c6) AND (col3.c6 <> col7.c6) AND (col3.c6 <> col8.c6) AND (col3.c6 <> col9.c6) AND (col3.c7 <> col4.c7) AND (col3.c7 <> col5.c7) AND (col3.c7 <> col6.c7) AND (col3.c7 <> col7.c7) AND (col3.c7 <> col8.c7) AND (col3.c7 <> col9.c7) AND (col3.c8 <> col4.c8) AND (col3.c8 <> col5.c8) AND (col3.c8 <> col6.c8) AND (col3.c8 <> col7.c8) AND (col3.c8 <> col8.c8) AND (col3.c8 <> col9.c8) AND (col3.c9 <> col4.c9) AND (col3.c9 <> col5.c9) AND (col3.c9 <> col6.c9) AND (col3.c9 <> col7.c9) AND (col3.c9 <> col8.c9) AND (col3.c9 <> col9.c9) AND (col4.c1 <> col5.c1) AND (col4.c1 <> col6.c1) AND (col4.c1 <> col7.c1) AND
(col4.c1 <> col8.c1) AND (col4.c1 <> col9.c1) AND (col4.c2 <> col5.c2) AND (col4.c2 <> col6.c2) AND (col4.c2 <> col7.c2) AND (col4.c2 <> col8.c2) AND (col4.c2 <> col9.c2) AND (col4.c3 <> col5.c3) AND (col4.c3 <> col6.c3) AND (col4.c3 <> col7.c3) AND (col4.c3 <> col8.c3) AND (col4.c3 <> col9.c3) AND (col4.c4 <> col5.c4) AND (col4.c4 <> col6.c4) AND (col4.c4 <> col7.c4) AND (col4.c4 <> col8.c4) AND (col4.c4 <> col9.c4) AND (col4.c5 <> col5.c5) AND (col4.c5 <> col6.c5) AND (col4.c5 <> col7.c5) AND (col4.c5 <> col8.c5) AND (col4.c5 <> col9.c5) AND (col4.c6 <> col5.c6) AND (col4.c6 <> col6.c6) AND (col4.c6 <> col7.c6) AND (col4.c6 <> col8.c6) AND (col4.c6 <> col9.c6) AND (col4.c7 <> col5.c7) AND (col4.c7 <> col6.c7) AND (col4.c7 <> col7.c7) AND (col4.c7 <> col8.c7) AND (col4.c7 <> col9.c7) AND
(col4.c8 <> col5.c8) AND (col4.c8 <> col6.c8) AND (col4.c8 <> col7.c8) AND (col4.c8 <> col8.c8) AND (col4.c8 <> col9.c8) AND (col4.c9 <> col5.c9) AND (col4.c9 <> col6.c9) AND (col4.c9 <> col7.c9) AND (col4.c9 <> col8.c9) AND (col4.c9 <> col9.c9) AND (col5.c1 <> col6.c1) AND (col5.c1 <> col7.c1) AND (col5.c1 <> col8.c1) AND (col5.c1 <> col9.c1) AND (col5.c2 <> col6.c2) AND (col5.c2 <> col7.c2) AND (col5.c2 <> col8.c2) AND (col5.c2 <> col9.c2) AND (col5.c3 <> col6.c3) AND (col5.c3 <> col7.c3) AND (col5.c3 <> col8.c3) AND (col5.c3 <> col9.c3) AND (col5.c4 <> col6.c4) AND (col5.c4 <> col7.c4) AND (col5.c4 <> col8.c4) AND (col5.c4 <> col9.c4) AND (col5.c5 <> col6.c5) AND (col5.c5 <> col7.c5) AND (col5.c5 <> col8.c5) AND (col5.c5 <> col9.c5) AND (col5.c6 <> col6.c6) AND (col5.c6 <> col7.c6) AND
(col5.c6 <> col8.c6) AND (col5.c6 <> col9.c6) AND (col5.c7 <> col6.c7) AND (col5.c7 <> col7.c7) AND (col5.c7 <> col8.c7) AND (col5.c7 <> col9.c7) AND (col5.c8 <> col6.c8) AND (col5.c8 <> col7.c8) AND (col5.c8 <> col8.c8) AND (col5.c8 <> col9.c8) AND (col5.c9 <> col6.c9) AND (col5.c9 <> col7.c9) AND (col5.c9 <> col8.c9) AND (col5.c9 <> col9.c9) AND (col6.c1 <> col7.c1) AND (col6.c1 <> col8.c1) AND (col6.c1 <> col9.c1) AND (col6.c2 <> col7.c2) AND (col6.c2 <> col8.c2) AND (col6.c2 <> col9.c2) AND (col6.c3 <> col7.c3) AND (col6.c3 <> col8.c3) AND (col6.c3 <> col9.c3) AND (col6.c4 <> col7.c4) AND (col6.c4 <> col8.c4) AND (col6.c4 <> col9.c4) AND (col6.c5 <> col7.c5) AND (col6.c5 <> col8.c5) AND (col6.c5 <> col9.c5) AND (col6.c6 <> col7.c6) AND (col6.c6 <> col8.c6) AND (col6.c6 <> col9.c6) AND
(col6.c7 <> col7.c7) AND (col6.c7 <> col8.c7) AND (col6.c7 <> col9.c7) AND (col6.c8 <> col7.c8) AND (col6.c8 <> col8.c8) AND (col6.c8 <> col9.c8) AND (col6.c9 <> col7.c9) AND (col6.c9 <> col8.c9) AND (col6.c9 <> col9.c9) AND (col7.c1 <> col8.c1) AND (col7.c1 <> col9.c1) AND (col7.c2 <> col8.c2) AND (col7.c2 <> col9.c2) AND (col7.c3 <> col8.c3) AND (col7.c3 <> col9.c3) AND (col7.c4 <> col8.c4) AND (col7.c4 <> col9.c4) AND (col7.c5 <> col8.c5) AND (col7.c5 <> col9.c5) AND (col7.c6 <> col8.c6) AND (col7.c6 <> col9.c6) AND (col7.c7 <> col8.c7) AND (col7.c7 <> col9.c7) AND (col7.c8 <> col8.c8) AND (col7.c8 <> col9.c8) AND (col7.c9 <> col8.c9) AND (col7.c9 <> col9.c9) AND (col8.c1 <> col9.c1) AND (col8.c2 <> col9.c2) AND (col8.c3 <> col9.c3) AND (col8.c4 <> col9.c4) AND (col8.c5 <> col9.c5) AND
(col8.c6 <> col9.c6) AND (col8.c7 <> col9.c7) AND (col8.c8 <> col9.c8) AND (col8.c9 <> col9.c9) AND
-- Nombres uniques dans chaque maison de 3x3
(col1.c1 <> col1.c2) AND (col1.c1 <> col1.c3) AND (col1.c1 <> col2.c2) AND (col1.c1 <> col2.c3) AND (col1.c1 <> col3.c2) AND (col1.c1 <> col3.c3) AND (col1.c2 <> col1.c3) AND (col1.c2 <> col2.c1) AND (col1.c2 <> col2.c3) AND (col1.c2 <> col3.c1) AND (col1.c2 <> col3.c3) AND (col1.c3 <> col2.c1) AND (col1.c3 <> col2.c2) AND (col1.c3 <> col3.c1) AND (col1.c3 <> col3.c2) AND (col1.c4 <> col1.c5) AND (col1.c4 <> col1.c6) AND (col1.c4 <> col2.c5) AND (col1.c4 <> col2.c6) AND (col1.c4 <> col3.c5) AND (col1.c4 <> col3.c6) AND (col1.c5 <> col1.c6) AND (col1.c5 <> col2.c4) AND (col1.c5 <> col2.c6) AND (col1.c5 <> col3.c4) AND (col1.c5 <> col3.c6) AND (col1.c6 <> col2.c4) AND (col1.c6 <> col2.c5) AND (col1.c6 <> col3.c4) AND (col1.c6 <> col3.c5) AND (col1.c7 <> col1.c8) AND (col1.c7 <> col1.c9) AND
(col1.c7 <> col2.c8) AND (col1.c7 <> col2.c9) AND (col1.c7 <> col3.c8) AND (col1.c7 <> col3.c9) AND (col1.c8 <> col1.c9) AND (col1.c8 <> col2.c7) AND (col1.c8 <> col2.c9) AND (col1.c8 <> col3.c7) AND (col1.c8 <> col3.c9) AND (col1.c9 <> col2.c7) AND (col1.c9 <> col2.c8) AND (col1.c9 <> col3.c7) AND (col1.c9 <> col3.c8) AND (col2.c1 <> col2.c2) AND (col2.c1 <> col2.c3) AND (col2.c1 <> col3.c2) AND (col2.c1 <> col3.c3) AND (col2.c2 <> col2.c3) AND (col2.c2 <> col3.c1) AND (col2.c2 <> col3.c3) AND (col2.c3 <> col3.c1) AND (col2.c3 <> col3.c2) AND (col2.c4 <> col2.c5) AND (col2.c4 <> col2.c6) AND (col2.c4 <> col3.c5) AND (col2.c4 <> col3.c6) AND (col2.c5 <> col2.c6) AND (col2.c5 <> col3.c4) AND (col2.c5 <> col3.c6) AND (col2.c6 <> col3.c4) AND (col2.c6 <> col3.c5) AND (col2.c7 <> col2.c8) AND
(col2.c7 <> col2.c9) AND (col2.c7 <> col3.c8) AND (col2.c7 <> col3.c9) AND (col2.c8 <> col2.c9) AND (col2.c8 <> col3.c7) AND (col2.c8 <> col3.c9) AND (col2.c9 <> col3.c7) AND (col2.c9 <> col3.c8) AND (col3.c1 <> col3.c2) AND (col3.c1 <> col3.c3) AND (col3.c2 <> col3.c3) AND (col3.c4 <> col3.c5) AND (col3.c4 <> col3.c6) AND (col3.c5 <> col3.c6) AND (col3.c7 <> col3.c8) AND (col3.c7 <> col3.c9) AND (col3.c8 <> col3.c9) AND (col4.c1 <> col4.c2) AND (col4.c1 <> col4.c3) AND (col4.c1 <> col5.c2) AND (col4.c1 <> col5.c3) AND (col4.c1 <> col6.c2) AND (col4.c1 <> col6.c3) AND (col4.c2 <> col4.c3) AND (col4.c2 <> col5.c1) AND (col4.c2 <> col5.c3) AND (col4.c2 <> col6.c1) AND (col4.c2 <> col6.c3) AND (col4.c3 <> col5.c1) AND (col4.c3 <> col5.c2) AND (col4.c3 <> col6.c1) AND (col4.c3 <> col6.c2) AND
(col4.c4 <> col4.c5) AND (col4.c4 <> col4.c6) AND (col4.c4 <> col5.c5) AND (col4.c4 <> col5.c6) AND (col4.c4 <> col6.c5) AND (col4.c4 <> col6.c6) AND (col4.c5 <> col4.c6) AND (col4.c5 <> col5.c4) AND (col4.c5 <> col5.c6) AND (col4.c5 <> col6.c4) AND (col4.c5 <> col6.c6) AND (col4.c6 <> col5.c4) AND (col4.c6 <> col5.c5) AND (col4.c6 <> col6.c4) AND (col4.c6 <> col6.c5) AND (col4.c7 <> col4.c8) AND (col4.c7 <> col4.c9) AND (col4.c7 <> col5.c8) AND (col4.c7 <> col5.c9) AND (col4.c7 <> col6.c8) AND (col4.c7 <> col6.c9) AND (col4.c8 <> col4.c9) AND (col4.c8 <> col5.c7) AND (col4.c8 <> col5.c9) AND (col4.c8 <> col6.c7) AND (col4.c8 <> col6.c9) AND (col4.c9 <> col5.c7) AND (col4.c9 <> col5.c8) AND (col4.c9 <> col6.c7) AND (col4.c9 <> col6.c8) AND (col5.c1 <> col5.c2) AND (col5.c1 <> col5.c3) AND
(col5.c1 <> col6.c2) AND (col5.c1 <> col6.c3) AND (col5.c2 <> col5.c3) AND (col5.c2 <> col6.c1) AND (col5.c2 <> col6.c3) AND (col5.c3 <> col6.c1) AND (col5.c3 <> col6.c2) AND (col5.c4 <> col5.c5) AND (col5.c4 <> col5.c6) AND (col5.c4 <> col6.c5) AND (col5.c4 <> col6.c6) AND (col5.c5 <> col5.c6) AND (col5.c5 <> col6.c4) AND (col5.c5 <> col6.c6) AND (col5.c6 <> col6.c4) AND (col5.c6 <> col6.c5) AND (col5.c7 <> col5.c8) AND (col5.c7 <> col5.c9) AND (col5.c7 <> col6.c8) AND (col5.c7 <> col6.c9) AND (col5.c8 <> col5.c9) AND (col5.c8 <> col6.c7) AND (col5.c8 <> col6.c9) AND (col5.c9 <> col6.c7) AND (col5.c9 <> col6.c8) AND (col6.c1 <> col6.c2) AND (col6.c1 <> col6.c3) AND (col6.c2 <> col6.c3) AND (col6.c4 <> col6.c5) AND (col6.c4 <> col6.c6) AND (col6.c5 <> col6.c6) AND (col6.c7 <> col6.c8) AND
(col6.c7 <> col6.c9) AND (col6.c8 <> col6.c9) AND (col7.c1 <> col7.c2) AND (col7.c1 <> col7.c3) AND (col7.c1 <> col8.c2) AND (col7.c1 <> col8.c3) AND (col7.c1 <> col9.c2) AND (col7.c1 <> col9.c3) AND (col7.c2 <> col7.c3) AND (col7.c2 <> col8.c1) AND (col7.c2 <> col8.c3) AND (col7.c2 <> col9.c1) AND (col7.c2 <> col9.c3) AND (col7.c3 <> col8.c1) AND (col7.c3 <> col8.c2) AND (col7.c3 <> col9.c1) AND (col7.c3 <> col9.c2) AND (col7.c4 <> col7.c5) AND (col7.c4 <> col7.c6) AND (col7.c4 <> col8.c5) AND (col7.c4 <> col8.c6) AND (col7.c4 <> col9.c5) AND (col7.c4 <> col9.c6) AND (col7.c5 <> col7.c6) AND (col7.c5 <> col8.c4) AND (col7.c5 <> col8.c6) AND (col7.c5 <> col9.c4) AND (col7.c5 <> col9.c6) AND (col7.c6 <> col8.c4) AND (col7.c6 <> col8.c5) AND (col7.c6 <> col9.c4) AND (col7.c6 <> col9.c5) AND
(col7.c7 <> col7.c8) AND (col7.c7 <> col7.c9) AND (col7.c7 <> col8.c8) AND (col7.c7 <> col8.c9) AND (col7.c7 <> col9.c8) AND (col7.c7 <> col9.c9) AND (col7.c8 <> col7.c9) AND (col7.c8 <> col8.c7) AND (col7.c8 <> col8.c9) AND (col7.c8 <> col9.c7) AND (col7.c8 <> col9.c9) AND (col7.c9 <> col8.c7) AND (col7.c9 <> col8.c8) AND (col7.c9 <> col9.c7) AND (col7.c9 <> col9.c8) AND (col8.c1 <> col8.c2) AND (col8.c1 <> col8.c3) AND (col8.c1 <> col9.c2) AND (col8.c1 <> col9.c3) AND (col8.c2 <> col8.c3) AND (col8.c2 <> col9.c1) AND (col8.c2 <> col9.c3) AND (col8.c3 <> col9.c1) AND (col8.c3 <> col9.c2) AND (col8.c4 <> col8.c5) AND (col8.c4 <> col8.c6) AND (col8.c4 <> col9.c5) AND (col8.c4 <> col9.c6) AND (col8.c5 <> col8.c6) AND (col8.c5 <> col9.c4) AND (col8.c5 <> col9.c6) AND (col8.c6 <> col9.c4) AND
(col8.c6 <> col9.c5) AND (col8.c7 <> col8.c8) AND (col8.c7 <> col8.c9) AND (col8.c7 <> col9.c8) AND (col8.c7 <> col9.c9) AND (col8.c8 <> col8.c9) AND (col8.c8 <> col9.c7) AND (col8.c8 <> col9.c9) AND (col8.c9 <> col9.c7) AND (col8.c9 <> col9.c8) AND (col9.c1 <> col9.c2) AND (col9.c1 <> col9.c3) AND (col9.c2 <> col9.c3) AND (col9.c4 <> col9.c5) AND (col9.c4 <> col9.c6) AND (col9.c5 <> col9.c6) AND (col9.c7 <> col9.c8) AND (col9.c7 <> col9.c9) AND (col9.c8 <> col9.c9);
```

Maintenant, chers lecteurs, patientez un peu!

ATTENTION : n’allez surtout pas essayer de solutionner une grille  avant de passer au prochain point!

Pour l’instant, contentez-vous seulement de créer la nouvelle vue sudoku_combined_view :

```USE sudoku;

CREATE VIEW sudoku_combined_view AS
SELECT t1.*
FROM sudoku_rows_view t1
INNER JOIN sudoku_columns_view t2
ON

-- Jointures entre représentation-colonnes et représentation-rangées
(t1.r1c1 = t2.r1c1) AND (t1.r1c2 = t2.r1c2) AND (t1.r1c3 = t2.r1c3) AND (t1.r1c4 = t2.r1c4) AND
(t1.r1c5 = t2.r1c5) AND (t1.r1c6 = t2.r1c6) AND (t1.r1c7 = t2.r1c7) AND (t1.r1c8 = t2.r1c8) AND
(t1.r1c9 = t2.r1c9) AND (t1.r2c1 = t2.r2c1) AND (t1.r2c2 = t2.r2c2) AND (t1.r2c3 = t2.r2c3) AND
(t1.r2c4 = t2.r2c4) AND (t1.r2c5 = t2.r2c5) AND (t1.r2c6 = t2.r2c6) AND (t1.r2c7 = t2.r2c7) AND
(t1.r2c8 = t2.r2c8) AND (t1.r2c9 = t2.r2c9) AND (t1.r3c1 = t2.r3c1) AND (t1.r3c2 = t2.r3c2) AND
(t1.r3c3 = t2.r3c3) AND (t1.r3c4 = t2.r3c4) AND (t1.r3c5 = t2.r3c5) AND (t1.r3c6 = t2.r3c6) AND
(t1.r3c7 = t2.r3c7) AND (t1.r3c8 = t2.r3c8) AND (t1.r3c9 = t2.r3c9) AND (t1.r4c1 = t2.r4c1) AND
(t1.r4c2 = t2.r4c2) AND (t1.r4c3 = t2.r4c3) AND (t1.r4c4 = t2.r4c4) AND (t1.r4c5 = t2.r4c5) AND
(t1.r4c6 = t2.r4c6) AND (t1.r4c7 = t2.r4c7) AND (t1.r4c8 = t2.r4c8) AND (t1.r4c9 = t2.r4c9) AND
(t1.r5c1 = t2.r5c1) AND (t1.r5c2 = t2.r5c2) AND (t1.r5c3 = t2.r5c3) AND (t1.r5c4 = t2.r5c4) AND
(t1.r5c5 = t2.r5c5) AND (t1.r5c6 = t2.r5c6) AND (t1.r5c7 = t2.r5c7) AND (t1.r5c8 = t2.r5c8) AND
(t1.r5c9 = t2.r5c9) AND (t1.r6c1 = t2.r6c1) AND (t1.r6c2 = t2.r6c2) AND (t1.r6c3 = t2.r6c3) AND
(t1.r6c4 = t2.r6c4) AND (t1.r6c5 = t2.r6c5) AND (t1.r6c6 = t2.r6c6) AND (t1.r6c7 = t2.r6c7) AND
(t1.r6c8 = t2.r6c8) AND (t1.r6c9 = t2.r6c9) AND (t1.r7c1 = t2.r7c1) AND (t1.r7c2 = t2.r7c2) AND
(t1.r7c3 = t2.r7c3) AND (t1.r7c4 = t2.r7c4) AND (t1.r7c5 = t2.r7c5) AND (t1.r7c6 = t2.r7c6) AND
(t1.r7c7 = t2.r7c7) AND (t1.r7c8 = t2.r7c8) AND (t1.r7c9 = t2.r7c9) AND (t1.r8c1 = t2.r8c1) AND
(t1.r8c2 = t2.r8c2) AND (t1.r8c3 = t2.r8c3) AND (t1.r8c4 = t2.r8c4) AND (t1.r8c5 = t2.r8c5) AND
(t1.r8c6 = t2.r8c6) AND (t1.r8c7 = t2.r8c7) AND (t1.r8c8 = t2.r8c8) AND (t1.r8c9 = t2.r8c9) AND
(t1.r9c1 = t2.r9c1) AND (t1.r9c2 = t2.r9c2) AND (t1.r9c3 = t2.r9c3) AND (t1.r9c4 = t2.r9c4) AND
(t1.r9c5 = t2.r9c5) AND (t1.r9c6 = t2.r9c6) AND (t1.r9c7 = t2.r9c7) AND (t1.r9c8 = t2.r9c8) AND
(t1.r9c9 = t2.r9c9);
```

4. L’optimisateur de plan

Avant de tenter d’exécuter la requête de la grille présentée au point 1 de cet article, quelques explications sont de mise. Il appert que notre nouvelle façon de faire change radicalement les choses!

En effet, au lieu de joindre seulement 9 tables comme c’était le cas avec sudoku_rows_view, notre nouvelle solution joint 9 tables une première fois (sudoku_rows_view), encore une fois 9 tables (sudoku_columns_view) puis regroupe les résultats de ces 2 vues dans sudoku_combined_view.

Il faut savoir que l’optimisateur de requêtes de MySQL, par défaut, énumère toutes les jointures possibles pour déterminer le plan d’accès qu’il considère comme optimal. Dans le cas qui nous intéresse, l’optimisateur détecte donc 18 tables indirectement référencées par la vue sudoku_combined_view et aura donc à examiner 18! (18 factorielle) jointures possibles, c’est-à-dire un total de 6402373705728000 jointures! Si par malheur vous tentiez d’exécuter la requête sur la vue sudoku_combined_view, il vous faudrait attendre une éternité avant que MySQL détermine un plan d’accès!  Pour vérifier, j’ai laissé rouler une requête de EXPLAIN sur la vue sudoku_combined_view pendant 2 jours avant de l’arrêter…

Heureusement, il existe une variable système nous permettant de contrôler le zèle de l’optimisateur de requêtes!  Cette variable s’appelle optimizer_search_depth.  Elle détermine la profondeur d’analyse de l’optimisateur quand celui-ci essaie de trouver le plan d’accès optimal.  À quoi bon un plan d’accès optimal si celui-ci prend 3 semaines à être généré ?  En ce qui nous concerne, un plan d’accès non optimal mais généré rapidement, compte tenu des 18 tables, est ce que nous recherchons!

La variable optimizer_search_depth peut être changée dans les fichiers de configuration de MySQL ou dynamiquement au beau milieu d’une session.  Prenez garde toutefois!  Si vous changez cette variable dans une session et non au niveau des fichiers de configuration, la nouvelle valeur de la variable ne s’applique qu’à la session!

Réglons cette valeur à 3  pour l’instant (plus de détails quant à cette valeur dans le prochain article)  :

```
set @@optimizer_search_depth = 3;

```

Maintenant, nous pouvons exécuter notre requête :

```
SELECT *
FROM sudoku_combined_view
WHERE
(r2c1 = 1) AND (r2c2 = 3) AND (r2c3 = 4) AND (r2c4 = 8) AND
(r2c5 = 2) AND (r2c6 = 5) AND (r2c7 = 6) AND (r2c8 = 9) AND
(r2c9 = 7) AND (r3c1 = 7) AND (r3c2 = 5) AND (r3c3 = 9) AND
(r3c4 = 3) AND (r3c5 = 6) AND (r3c6 = 4) AND (r3c7 = 1) AND
(r3c8 = 8) AND (r3c9 = 2) AND (r4c1 = 3) AND (r4c2 = 9) AND
(r4c3 = 7) AND (r4c4 = 1) AND (r4c5 = 8) AND (r4c6 = 2) AND
(r4c7 = 5) AND (r4c8 = 6) AND (r4c9 = 4) AND (r6c1 = 5) AND
(r6c2 = 8) AND (r6c3 = 1) AND (r6c4 = 4) AND (r6c5 = 7) AND
(r6c6 = 6) AND (r6c7 = 2) AND (r6c8 = 3) AND (r6c9 = 9) AND
(r7c1 = 8) AND (r7c2 = 2) AND (r7c3 = 5) AND (r7c4 = 6) AND
(r7c5 = 4) AND (r7c6 = 1) AND (r7c7 = 9) AND (r7c8 = 7) AND
(r7c9 = 3) AND (r8c1 = 9) AND (r8c2 = 7) AND (r8c3 = 6) AND
(r8c4 = 5) AND (r8c5 = 3) AND (r8c6 = 8) AND (r8c7 = 4) AND
(r8c8 = 2) AND (r8c9 = 1);

```

Fantastique!  1.08 seconde!  Est-il possible d’extraire plus de jus de ce citron?

Voyons ce que le EXPLAIN a à nous dire :

```+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-------------------------------+------+--------------------------------------------------------------+
| id | select_type | table | type        | possible_keys                                                                                                                                      | key         | key_len | ref                           | rows | Extra                                                        |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-------------------------------+------+--------------------------------------------------------------+
|  1 | SIMPLE      | col3  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i38,i48 | 2,2,2   | NULL                          |   64 | Using intersect(i23,i38,i48); Using where                    |
|  1 | SIMPLE      | col9  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i78,i68,i48 | 2,2,2   | NULL                          |   65 | Using intersect(i78,i68,i48); Using where; Using join buffer |
|  1 | SIMPLE      | r2    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i29     | 2,2     | NULL                          |   68 | Using intersect(i37,i29); Using where; Using join buffer     |
|  1 | SIMPLE      | r3    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i28     | 2,2     | NULL                          |   68 | Using intersect(i37,i28); Using where; Using join buffer     |
|  1 | SIMPLE      | r4    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i56,i29     | 2,2     | NULL                          |   68 | Using intersect(i56,i29); Using where; Using join buffer     |
|  1 | SIMPLE      | r6    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12,i35     | 2,2     | NULL                          |   68 | Using intersect(i12,i35); Using where; Using join buffer     |
|  1 | SIMPLE      | r7    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12,i68     | 2,2     | NULL                          |   68 | Using intersect(i12,i68); Using where; Using join buffer     |
|  1 | SIMPLE      | col1  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i67     | 2,2     | NULL                          |   68 | Using intersect(i23,i67); Using where; Using join buffer     |
|  1 | SIMPLE      | col2  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer     |
|  1 | SIMPLE      | col4  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i78,i46     | 2,2     | NULL                          |   68 | Using intersect(i78,i46); Using where; Using join buffer     |
|  1 | SIMPLE      | col5  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer     |
|  1 | SIMPLE      | col6  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i67     | 2,2     | NULL                          |   68 | Using intersect(i23,i67); Using where; Using join buffer     |
|  1 | SIMPLE      | r8    | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i79,i38 | 2,2,2   | NULL                          |   78 | Using intersect(i37,i79,i38); Using where; Using join buffer |
|  1 | SIMPLE      | col8  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i37,i24     | 2,2     | NULL                          |   68 | Using intersect(i37,i24); Using where; Using join buffer     |
|  1 | SIMPLE      | col7  | index_merge | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i23,i68     | 2,2     | NULL                          |   68 | Using intersect(i23,i68); Using where; Using join buffer     |
|  1 | SIMPLE      | r1    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.col1.c1,sudoku.col2.c1 | 5040 | Using where                                                  |
|  1 | SIMPLE      | r5    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.col1.c5,sudoku.col2.c5 | 5040 | Using where                                                  |
|  1 | SIMPLE      | r9    | ref         | i12,i13,i14,i15,i16,i17,i18,i19,i23,i24,i25,i26,i27,i28,i29,i34,i35,i36,i37,i38,i39,i45,i46,i47,i48,i49,i56,i57,i58,i59,i67,i68,i69,i78,i79,i89,i9 | i12         | 2       | sudoku.col1.c9,sudoku.col2.c9 | 5040 | Using where                                                  |
+----+-------------+-------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------+-------------+---------+-------------------------------+------+--------------------------------------------------------------+
18 rows in set (0.28 sec)
```

5. Optimisation de la table

Il existe quelques trucs d’optimisation de table que nous avons omis de faire.  C’est peut-être le temps d’y songer pour extraire chaque milliseconde et chaque octet possible!

Bien que la table positions ne subisse jamais de UPDATE, de INSERT ou de DELETE, sommes-nous certains que les pages d’index sont triées ? Pour ce faire, nous pourrions exécuter un OPTIMIZE TABLE sur la table positions.  Ce serait inutile dans notre cas.  Pourquoi?  Parce que les permutations générées pour créer les requêtes d’insertion dans la table positions ont été générées dans l’ordre des index.

D’autre part, comme la table n’a connu aucune modification, un ANALYZE TABLE serait, lui aussi, totalement inutile!

Changer la définition de la table avec un ALTER TABLE pour y inclure AVG_ROW_LENGTH et MAX_ROWS ?  Pas plus utile.  Comme le format des lignes dans la table positions est Fixed et que la table est de format MyISAM, ces deux valeurs n’ont pas à être forcées puisque MySQL les détermine sans notre aide!

6. Impossible n’est pas français!

Est-ce possible de faire mieux?  En éternel optimiste et têtu que je suis, je répondrai « oui » !  Mais comment?

Seulement, avons-nous tout prévu?  Que faire avec une grille contenant des lignes vides et des colonnes vides comme la grille suivante :

Suite au prochain article!