数据库编程大赛冠军:郑凌云:0.67秒通过百万级数据评测!SQL代码惊现神之一手!

12月27日,NineData和云数据库技术社区主办,华为云、火山引擎、开源中国、云和恩墨、TDengine、云猿生数据、DORIS、ITPUB等协办单位和媒体,共同举办了本次《数据库编程大赛》。大赛题目「用一条SQL给出扑克牌24点的计算表达式」。

以下冠军选手郑凌云的参赛情况的介绍:

图片

参赛选手:郑凌云

个人简介:淘宝,负责推荐系统开发

参赛数据库:MySQL

性能评测:百万级数据代码性能评测 0.67秒

综合得分:95

以下是郑凌云选手的代码说明思路简介:

0. 核心:因为4张牌计算24点时的顺序可任意互换,所以不同排列的4张牌可视为同一组合。采用质数编码,把1到10映射成2到29内的质数,4张牌的积可作为该组合的唯一编码

1. 本地写代码,通过简单的回溯算法,生成24点游戏的所有解:152,((1+1)+1)*8,156,(6*2)*(1+1),...

2. 受限于代码大小10k限制,通过把上一步生成的数据进行压缩:SELECT REPLACE(TO_BASE64(COMPRESS('152,((1+1)+1)*8,156,(6*2)*(1+1),...')), '\n', '')

3. 提交的代码中,先对上一步生成的数据解压缩:UNCOMPRESS(FROM_BASE64('XXXX')),并通过递归CTE生成查询表:152,((1+1)+1)*8;156,(6*2)*(1+1);...

4. 对输入表LEFT JOIN上一步生成的查询表,关联的键值是对c1,c2,c3,c4做质数编码后的积。

以下是郑凌云选手的算法说明,结尾附完整SQL:


算法说明

看到题目是用SQL算24点,感觉挺有意思的,平时使用SQL最多就是简单SELECT一下,从未想过是否可以算24点,就想挑战一下。

阶段一

结合题目条件,分析了一下这个24点游戏的问题。待求解的输入行数比较多,但4张1到10的牌的组合最多只有715种。在这个前提下,自然是先计算出715种组合的所有结果后,再进行LEFT JOIN。

先计算715种组合的结果

大概有两种思路:

1. 求解的方法

2. 构造的方法

求解的方法

即先遍历715种组合,通过回溯法计算每个组合的解(思路就是4个数算24,先4选2,进行加减乘除反向减反向除6种运算,问题化简为3个数算24;然后继续该过程直到最终化简为1个数算24,需要的计算量在4573左右),复杂度在 715 * 4573 = 327万左右。

构造的方法

4个数算24,本质上其实只有两种形式,即:

((a op b) op c) op d = 24

或者

(a op b) op (c op d) = 24

则可以构造出所有1到10的数字进行这两种形式计算,看结果是否能等于24。(可以这样理解:算24第一步肯定是2张牌进行计算;第二步则有两种选择,要么和第3张牌计算,要么和剩下的两张牌计算的结果进行计算)

其中还有两个优化点:

1. x op y (x和y是两张牌的原始点数,而不是计算结果)有两种算法:一是x和y都可以取1到10之间的数,op有加减乘除4种,那总共有400种(很明显其中有重复的);二是限制y必须大于等于x,op有加减乘除反向减反向除6种,那总共有330种。我们会选择复杂度小的330种这种方式。

2. ((a op b) op c) op d = 24 这种形式,如果直接计算,复杂度在 330 * 6 * 10 * 6 * 10 = 119万左右,而如果从24反向计算回最后一个数,即 ((24 op d) op c) op b = a,其中a是1到10中的某整数,复杂度在 1 * 6 * 10 * 6 * 10 * 6 * 10 = 22万左右。我们选择复杂度小的22万种这种方式。

对于 (a op b) op (c op d) = 24 这种形式,复杂度约 330 * 6 * 330 / 2 = 33万左右(这个表达式是估算的,我没有进行严格计算)。两种形式加起来复杂度在55万左右,比第一种思路的复杂度327万会低很多。所以我们采用第二种思路。

再进行LEFT JOIN

JOIN需要一个关联条件,怎么唯一表示4个数的组合呢?可以排序,可以用带计数的map甚至bitmap,还可以用质数编码后的乘积表示。我采用了质数编码。其实bitmap或许性能更高,但需要一些精细的操作,我并没有去比较过这两种方式的性能区别(有兴趣的人可以试一下),当时也没有纠结,就选了更习惯的质数编码。因为在这个阶段我和很多人一样陷入到怎么求解24点的问题中,并没有意识到JOIN的关键。

SQL代码

WITH RECURSIVEoperations(op) AS (VALUES ROW(1), ROW(2), ROW(3), ROW(4), ROW(5), ROW(6)),numbers(val, enc) AS (VALUES ROW(1, 2), ROW(2, 3), ROW(3, 5), ROW(4, 7), ROW(5, 11), ROW(6, 13), ROW(7, 17), ROW(8, 19), ROW(9, 23), ROW(10, 29)),reverse_combinations1(enc, val, rst) AS (SELECT enc, val, 24e0 FROM numbers),reverse_combinations1_solution(enc, rst, solution) AS (SELECTenc,CASE opWHEN 1 THEN val + rstWHEN 2 THEN val * rstWHEN 3 THEN val - rstWHEN 4 THEN rst - valWHEN 5 THEN val / rstWHEN 6 THEN rst / valEND,CASE opWHEN 1 THEN (12 << 4) | valWHEN 2 THEN (14 << 4) | valWHEN 3 THEN (val << 4) | 12WHEN 4 THEN (11 << 4) | valWHEN 5 THEN (val << 4) | 14WHEN 6 THEN (13 << 4) | valENDFROM reverse_combinations1 CROSS JOIN operations),reverse_combinations1_solution_faster AS (SELECT DISTINCT enc, rst, solution FROM reverse_combinations1_solution),reverse_combinations2(enc, val, rst, solution) AS (SELECT t1.enc * t2.enc, val, rst, solution FROM reverse_combinations1_solution_faster t1 CROSS JOIN numbers t2),reverse_combinations2_solution(enc, rst, solution) AS (SELECTenc,CASE opWHEN 1 THEN val + rstWHEN 2 THEN val * rstWHEN 3 THEN val - rstWHEN 4 THEN rst - valWHEN 5 THEN val / rstWHEN 6 THEN rst / valEND,CASE opWHEN 1 THEN (12 << 4) | val | (solution << 8)WHEN 2 THEN (14 << 4) | val | (solution << 8)WHEN 3 THEN (val << 4) | 12 | (solution << 8)WHEN 4 THEN (11 << 4) | val | (solution << 8)WHEN 5 THEN (val << 4) | 14 | (solution << 8)WHEN 6 THEN (13 << 4) | val | (solution << 8)ENDFROM reverse_combinations2 CROSS JOIN operations),reverse_combinations2_solution_faster2x AS (SELECT DISTINCT enc, rst, solution FROM reverse_combinations2_solution),reverse_combinations3(enc, val, rst, solution) AS (SELECT t1.enc * t2.enc, val, rst, solution FROM reverse_combinations2_solution_faster2x t1 CROSS JOIN numbers t2),reverse_combinations3_solution(enc, rst, solution) AS (SELECTenc,CASE opWHEN 1 THEN val + rstWHEN 2 THEN val * rstWHEN 3 THEN val - rstWHEN 4 THEN rst - valWHEN 5 THEN val / rstWHEN 6 THEN rst / valEND,CASE opWHEN 1 THEN (12 << 4) | val | (solution << 8)WHEN 2 THEN (14 << 4) | val | (solution << 8)WHEN 3 THEN (val << 4) | 12 | (solution << 8)WHEN 4 THEN (11 << 4) | val | (solution << 8)WHEN 5 THEN (val << 4) | 14 | (solution << 8)WHEN 6 THEN (13 << 4) | val | (solution << 8)ENDFROM reverse_combinations3 CROSS JOIN operations),reverse_combinations_solution(enc, solution) AS (SELECTenc *CASE ROUND(rst)WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END,ROUND(rst) | solution << 8FROM reverse_combinations3_solution WHERE (ROUND(rst) BETWEEN 1 AND 10) AND ABS(ROUND(rst) - rst) < 0.000001),reverse_combinations_solution_distinct(enc, solution) AS (SELECT enc, ANY_VALUE(solution) FROM reverse_combinations_solution GROUP BY enc),reverse_format_solution(enc, expr, solution) AS (SELECT enc, CAST((solution & 0x0F) AS CHAR), solution >> 8 FROM reverse_combinations_solution_distinctUNION ALLSELECT enc,CASE (solution & 0xF0) >> 4WHEN 11 THEN CONCAT('(', expr, '+', solution & 0x0F, ')')WHEN 12 THEN CONCAT('(', expr, '-', solution & 0x0F, ')')WHEN 13 THEN CONCAT('(', expr, '*', solution & 0x0F, ')')WHEN 14 THEN CONCAT('(', expr, '/', solution & 0x0F, ')')ELSECASE solution & 0x0FWHEN 12 THEN CONCAT('(', (solution & 0xF0) >> 4, '-', expr, ')')WHEN 14 THEN CONCAT('(', (solution & 0xF0) >> 4, '/', expr, ')')ENDEND,solution >> 8FROM reverse_format_solution WHERE solution > 0),reverse_solution(enc, expr) AS (SELECT enc, expr FROM reverse_format_solution WHERE solution = 0),combinations2(enc, c1, c2) AS (SELECT t1.enc * t2.enc, CAST(t1.val AS DOUBLE), CAST(t2.val AS DOUBLE)FROM numbers t1JOIN numbers t2 ON t1.val <= t2.val),combinations2_solution(enc, rst, expr) AS (SELECTenc,CASE opWHEN 1 THEN c1 + c2WHEN 2 THEN c1 * c2WHEN 3 THEN c1 - c2WHEN 4 THEN c2 - c1WHEN 5 THEN c1 / c2WHEN 6 THEN c2 / c1END,CASE opWHEN 1 THEN CONCAT('(', c1, '+', c2, ')')WHEN 2 THEN CONCAT('(', c1, '*', c2, ')')WHEN 3 THEN CONCAT('(', c1, '-', c2, ')')WHEN 4 THEN CONCAT('(', c2, '-', c1, ')')WHEN 5 THEN CONCAT('(', c1, '/', c2, ')')WHEN 6 THEN CONCAT('(', c2, '/', c1, ')')ENDFROM combinations2 CROSS JOIN operations),combinations2_solution_faster7x AS (SELECT DISTINCT enc, rst, expr FROM combinations2_solution),combinations4(enc1, enc2, rst1, rst2, expr1, expr2) AS (SELECT t1.enc, t2.enc, t1.rst, t2.rst, t1.expr, t2.exprFROM combinations2_solution_faster7x t1JOIN combinations2_solution_faster7x t2 ON t1.enc <= t2.enc),combinations4_faster2x AS (SELECT DISTINCT enc1, enc2, rst1, rst2, expr1, expr2 FROM combinations4),combinations4_solution(enc, rst, expr) AS (SELECTenc1 * enc2,CASE opWHEN 1 THEN rst1 + rst2WHEN 2 THEN rst1 * rst2WHEN 3 THEN rst1 - rst2WHEN 4 THEN rst2 - rst1WHEN 5 THEN rst1 / rst2WHEN 6 THEN rst2 / rst1END,CASE opWHEN 1 THEN CONCAT(expr1, '+', expr2)WHEN 2 THEN CONCAT(expr1, '*', expr2)WHEN 3 THEN CONCAT(expr1, '-', expr2)WHEN 4 THEN CONCAT(expr2, '-', expr1)WHEN 5 THEN CONCAT(expr1, '/', expr2)WHEN 6 THEN CONCAT(expr2, '/', expr1)ENDFROM combinations4_faster2x CROSS JOIN operations),solution(enc, expr) AS (SELECT enc, ANY_VALUE(expr) FROM combinations4_solution WHERE ABS(rst - 24) < 0.000001 GROUP BY enc),lookup_table(enc, result) AS (SELECT enc, ANY_VALUE(expr) FROM (SELECT enc, expr FROM solutionUNION ALLSELECT enc, expr FROM reverse_solution) t1 GROUP BY enc)SELECT id, c1, c2, c3, c4, resultFROM poker24.cardsLEFT JOIN lookup_table ON enc=CASE c1WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c2WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c3WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c4WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END

最后分析下性能

耗时:join(20ms) + 构造lookup_table(187ms) = 207ms

这里构造lookup_table的耗时,即为计算715种组合24点解的耗时。

阶段二

怎么更快地求解24点问题呢?因为前面计算出了结果,看了下其实只有566个答案,尝试直接把答案构造进SQL进行JOIN,发现超过了题目要求的10KB限制。我对SQL也不是很熟悉,一度放弃了该方案,直到发现MySQL中有COMPRESS()函数。。。

1. 通过 SELECT REPLACE(TO_BASE64(COMPRESS('152,((1+1)+1)*8,156,(6*2)*(1+1),...')), '\n', '') 把结果编码输出

2. 提交的代码中,先对上一步生成的数据解压缩:UNCOMPRESS(FROM_BASE64('XXXX')),并通过递归CTE生成查询表:152,((1+1)+1)*8;156,(6*2)*(1+1);...

3. 对输入表LEFT JOIN上一步生成的查询表,关联的键值是对c1,c2,c3,c4做质数编码后的乘积

SQL代码v1

决采用拼接union select或values()的长度超过10K字节限制的问题,主要采取了以下压缩空间的技巧:

WITH RECURSIVE lookup_table(enc,result,dat) AS(SELECT 0,'err_placeholder',UNCOMPRESS(FROM_BASE64('ICcAAHicTVpbkiMhDLvOTCZd4WUD97/YWpIhWzUf0zTY4Ics06nW3j8/9a/+xt9rvav5+8df7ffFwXcr4/0z8e6n8bktzH/F/Ib5bcb8/dz3fcT7Wv6ugDrK+2e8+hXY4tkosPPZy9mA/756CChHweTziucV6/9+aqh5D8zff1ee4X0tD5+woG4/Asfva7x7uTs2PvvACccViBPMhzPw3npYZGGtFPgY54QD81c9FnvVEjreY8UEe9mvZLxtxgQ7Av09YZIJ5RK4uus9N7zejg04Tq/3ey2c2H8/acHviV47rBQnnHcLM/xWwsjYpEbW71+4sTms3o5b6g6ZjV4xWr3DCH/3fS9+3s+HboSG9hw3jwr5mPq3f1/tba3R6l8FFm7oVCi31nIWdFq90+39KtzlKOgwkmH+pJv53ma6/cVJb8f8Hc+P3q+Zbm8vub3t2OGg2zhh+D0B3W7D5fYUOHGicDse8H7CQuM8r/d2BjaF4X1tFXEEden3CRvL75S4bNGvkhBuqjCSHI9lIcKGZryko5pkwm0Wlg03YVe1hB3/YiLWlGv5iAg4vzfFqzYWA2OFGj8DIXXucXbKeGlNtsiQfWLNhP/D3vM3lHxaKO4MOuidGSA4vwawkbbtnl9B1ypMpBEGXahpWLMicuVkhtXPQvI0rWGYMAwYJh3P/Bee62+zGyYdJnO9fw46LLthwveb7xdOFqERyc843M9VUIdloPRHgTL2FUl8mIgkIx5wxY5teqRerPiMX6YfdY7ws0Qylvk/VoXBvVIptwSRrXQpHd9tYMS5cSZgZQArODrtW6DGzj7DmiY1rxMcnRuJ4EASSAizQtAhIUy7eXYSrh/MI+2cA/seX8HReX6pUXC0xQPThgKD1lNqRljfPPCHM5hsu1+pCo5Om8hI6/cJBOmznOCg64wpvygkTIWRtq/YzaR37i3Kify732tU2uAPKSjT+kKMjfRGJGqZ6zh0KO0mgt0144kZjsCVRzVjMUHwvzzamKnh0ZHo0NZo16Na43scNSYHlobA+bEIGw44sltqNGMjdRdlmKKfMAslcvEY2Fmq0Zru93gO7/SyBVwjYaYPJKafAWD1EnSN9Lk1WERq5OJRBkFkXAcS0KfsASE25jgz6AsrMMk6UqNsVRxPDmVh3L2r9m9YXpVrzvF1F+3W3LM8fizkWIS1kNlOVJsJeu2YaRbCZJjFYKenRtByxF7HKoMelBDGrI2u7VqayQ1GCKtYpsZixQihfvXUImi1tOTy0s5OptB40XAq9oWLNn2IJQr07VWxYwePW1W1/Fs3+6vDVpum0sjwNBWHFJVW2td6DIfRie3+nIP7aC3hyj8r4GrS5KHe8+B7SQrP6S/VFFnYj/trW1W+i+xlpoQ3F4M15cQxaoeNN0/hCWpN4cpnTuqTmcNTSNnsSh0N0Yqdpt9UJv3BgbTJ+d0S03ZRnUYGK+yWh6ltsY6lZeWhqON+NqDC1XyuK3trA4wfyV7KZi9+DrcSjxXOD591ODscB1Qp1G9Qjvvc9mRQNpKmFkm1WWTb78Nnqx0WvfO91Xi/OTmWvOfqt/hLYLNTLfncq7GOt6yWY1sqhNConovvPy1J1fT7PFU97XDp9uAABSdStdSJejEBbv+l1ECkSmSUihE8rB/U44pV92HTKXLWA3oSWWkVcktVyzH2YRZDZmzzgp7WFFg2qdWnMT6nmFM8kfQ4bDXFk14UsiqZgOXGI3zojdiUKGuIwAxLc4M1GxzgHzjEqXcveiyngDk1uozbYvn0DSFYI6m976/THBaIhgZT5iOrh+JdZjK2JoCOWkgrf86U3mATGYkgElL7MRIiBq7eybj/yNPeXkpH+Dz3PNN8f/FCETONVVgRERHQ7NggoqC/t94/J2KiVt4BhkwdzQ4R73TwbEckROyggViStATZ8Z79zlBFrnaFkosHktgh4ykUkQuG8TSx7Y3QHmcgKvJA7O9YEvQBIdHL+KrNOMIURQ2ltoopdoSA2SC8RR8RGJFQ2Cr4Zhq1z20H8XmWwZ3ZI5bCpLTv8VSRmZaS6tzaZBYtmQjVaSwTQcwwMje7mCw9HVIndzI5sLD5lRyrodGF0QCaL1lg9m3iaX8KwCh62Mk6eqJGm6XilwZWc7uAKWdtYgDxkgO1lGIXsDstG1RGuPD0mzylbZKKljw6WPA8sSWatevFjiEyuvfhFBh9t7n7IUR0YTCIemKaMkbznlqy6wpmpjRmov+hv0ceqPRLyAaeiFoP5k4nnDx8IrnpQGJ5mUvctzJnHDwJarYPtZYQh15tnmARvds8fTpneBzn7JXUeu46r5elp7gAZhKlAk6J+aoRC1ZcDUZTaRyvxOhrgpl5TitxhI1X6JnJ+FrWagPYpZ+VHbWWfRytkVHKAd4/Yk3koTtFf2Bs2jx4HkTB3hmZvlTngr/pcmB1ohcyKtvYYu3gdQgCyzO7cKw+djb4nmRLORHZW8ljLb0UhVx6tCTENlUjy2iIzNrW6et560BxVl0WxSn6tUs/nG3z4N4SKLksqxSLMycRCaJMtXoYgSW+qEA/fCYqtUJ3PXZzMMqOcdbHLmTElqqC6Y93a0EsKzOBeEGS5r0n28oCV+kJcTQVp2jlKFhilJe2VVo8bRYljdU1eRxrWsvyOr+SCiJ1JZOj38tAkGFzz+bJgm2p4CzSRpyseFd2+impUer62SRrU1Syuf8rQqyI1cfE6ZLvEUMr9YWVJoNohnUHTLkeVk4Zl1VfkNdYFUdRRiW7Q1pGt1rv8bSHVhRs63PKaRiFwf+wmLKFhRFuhrDE9lLhOWWIRlapMgIhibU7IGt+zwcVuIJs+26LZT3AgEUCdZMXE2ue56erBE4WK91kdAalnRsCUL7wQLPThmvgFHPJWGA0ie5RJXhXShmnFGNNJYUclDqoZmtjsUK1uLHii8H1p5PFZi2mVFzdkQLkZUbMGKVZdseplwNZeWNVoKeE2tlHdDeiqp1Z2d/e27fQYsbcohHEGVpkcO+RIj0vf8zat9Biq16/VnVYZA5ahBlCGXu0/wot9bQ0wCTlme9VsEbBqTVzXlYM8783jreCdzysxwCZ3U5B76fvmf8VVpq+U1NWVo64/0eVoCASj4V18JIUBSGQiQPP8U+v63IljEZ775YXAPLPIJmgDPgoypv35EqPnB6N7bd8Z13t12OUaiz6dqSiXx6mKpqRM0lzlq4zcJzFdkI+3YzpWsUuCH1cFMBnB/k4sJy0RiWRAVmGWzasOk/tddutS65JVRxrsL/HSLYqU0dCX9FdLGte0UFV7eL8oAuskeBlXVRCLGnjs9pKq+m5kPRhToz+9Rx3Ft2a2yEiZHnBiJYd4mHaJDu0lVcZDAoaBLcDvP4IBs4NiWhoUSNdlhgEP/rOZYdqaI6PYQd4KbiVqR3S1NI12f+tR5WbkGLFTnXQsknDJnxq2VabmIUPk4b6RB4e4tDSqPUEPd28nHRfX99v5Xya/9Ew24my2aPC13mfPXrGs2fkVS8MLP87aV1l/p2Vj1viSSQn77QXqXpI8uxdooXfN7W1TAyZFUwm6Y19BA197rU7I1JDutheg3bjXReRJzySdmMs68NVX9dK0EBO/0Uf5rsNh+yOyk9mBH3DaIEsj/TKoAXwIBITGKxW/WcGcLH3r7scz52zFF83J9RGzqo4iV3msrH9ZgndZE7I2Se0J7+NyJkqcky4PhioYc1Oqop7RqUJGcJitofpBDRU//sJzC5NLQiLKiYF0/Fvf7EeYv/KjFdR5bSyvo0JbTddfRWGMBHJ4zPTKSKM9uyI1oqSx/vfIPS44SaB/oyE1KGLGbxUY2KrX27PJW51HqzjwFy8GdiYwp5270EakCA7AHXtXlpA13uSXpueSPKqH8o7hHSljXrwgXqqiWPprlPdc6ulny+SDuSpEZ+XG2rZIsPK7NdQ1InKFnowYoJhGS9aBKKLggKMLlvkKrTZX7YoQdPXZYuaFLL7KTCLI9E/7XuHQ9mjNlAumAj5GX17GK3DrDKRcQOV/DlgJkSZvmZ1NYkJkOgrCzqFcUYIB+uybtxFMYX6ZQ/GbXdyU6dtUT5BcuttDGXITX4n9USaFlSmH6ShnIA6kTtihrRFYb8dxZTZeLm0ElgHySS8r6DS55u5XRdDdnvZObdCZDFEkOc+DlHV8Ucb4u8EVlo7mGvn1c9nn4+bUSL2oVMqT8G5LW+Zrr7gt2xRPc8bLXnYn6Hvx0qtDZDnlViLkSlPwmT5zWj0JM9c9mEENPotsZaG49WYlAnEjI2rrjC4aozF/p6i88NRFNF6hoi+fU+fB2e4RyuVjSBpxPkIH6X14AwnoddWKO+zLuphr1+c4VicZdMCiazBuJbu53AWNeWAPvXtI7HPGm8dVBEm7W2m3v6jfaNzjmUSDU/pI3NXnjJ1YAhet0xF/MEwnIbBK9JNJA/LNV1wjuzQZliq3w6NgRENInw+jsJozSMudck8hJm4Gwh+0/9rYZgJEVLr21rthBlYOdM1ogh3+aWfEWQWSg6hIPPO+IMR3QbEQ8aYz68cRFqExlo3xriqR1m64aORXXg1QjkMH4vK9e2skcZRYX1d0euzUILWvBiDkHl7sO6a2BB2wjl8lHKxGqZCE1DuMoYMOOf0+h2Db4CProz1j+vzW+ATwCDzBTu3LlcR0ZAvkcHwy8Z9Ibuit3Vdjgnn9QkrGgaJViDGiPMLw8rvNFhmvKYQhjAVLfpGZZllaHo0u+cqHJHiUbx4zwbFHxwkjDLNx8xeXvC0Le/esAyRgsvg0vxGClLW2AbUeQgEN7Vb3RfYlMTR5yT6WSbxik5HKWQZv1HVilppBjBF1QCfpqoB+bpMstl4ETQPkPEKjFGW9zVRmqK49n4zkiS1gp/sYwkFfzTVc/4X/Jtsdpl/72f+wNzqHP1YniNBNwEdTg6+w/fBY2ZVLsurGHKm8s6rFsdvfVjy8jwMBq8MPrF5aAiTMiG5QraJQln/u32BpBo7b/24LClvCd7UD1TJaZEk895LYicgEJOfPhCjFwScNyKTmwejQtezvN69SsPajHdZQr8siiMSaYFLVIPOq+yrk5tG+XXvp4laMBiugUY6d92fMgW1Vy1LKMfvHILn/XfHwtKLPm26zj+/P3uqvDTUmLaHkiq3aH+TbQ8vDhUborjR+HheQWEzKS946EnLJYH/ALZfNLo='))UNION ALLSELECT CAST(SUBSTRING_INDEX(dat,',',1) AS SIGNED),SUBSTRING_INDEX(SUBSTRING_INDEX(dat,',',2),',',-1),SUBSTRING(dat,LENGTH(SUBSTRING_INDEX(dat,',',2))+2)FROM lookup_tableWHERE LENGTH(dat)>0)SELECT id, c1, c2, c3, c4, resultFROM poker24.cardsLEFT JOIN lookup_table ON enc=CASE c1WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c2WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c3WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c4WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END

分析下性能v1

耗时:join(152ms) + lookup_table(2ms) = 154ms

看起来是快了,但是当输入数据规模增大时,这还不如前面那个方法呢。问题来了,为什么这个join这么慢??

自然猜测数据库对阶段一中的代码和阶段二中的代码的优化不同。我并不是SQL专家,通过explain也没有发现有价值的线索(已经有'Materialize CTE',有'hash join'了),加优化hints也没用。为了让数据库做类似阶段一的优化,我尝试对lookup_table做了类似阶段一的一些复杂处理,其中验证了GROUP BY和DISTINCT操作都可以让数据库进入优化状态,看explain的结果,多出来的一步是在'hash join'前多了个'Using temporary'。

SQL代码v2

WITH RECURSIVE lookup_table(enc,result,dat) AS(SELECT 0,'err_placeholder',UNCOMPRESS(FROM_BASE64('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'))UNION ALLSELECT CAST(SUBSTRING_INDEX(dat,',',1) AS SIGNED),SUBSTRING_INDEX(SUBSTRING_INDEX(dat,',',2),',',-1),SUBSTRING(dat,LENGTH(SUBSTRING_INDEX(dat,',',2))+2)FROM lookup_tableWHERE LENGTH(dat)>0),lookup_table_faster5x AS (SELECT enc,ANY_VALUE(result) AS result FROM lookup_table GROUP BY enc)SELECT id, c1, c2, c3, c4, resultFROM poker24.cardsLEFT JOIN lookup_table_faster5x ON enc=CASE c1WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c2WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c3WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c4WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END

分析下性能v2

耗时:join(6ms) + lookup_table(3ms) = 9ms

当最终性能评测时,输入数据量是我们测试数据的100倍,所以预估性能评测的耗时在600ms左右,和最终测试结果基本吻合。

后记

答辩时有位评委老师(好像是周振兴老师?线上答辩也分不清哪位老师在说话,尴尬~)问到我阶段一的方法预估耗时会是多少,根据上面数据,预估值是在2秒左右。当时没有反应过来评委老师问题后面的问题。其实阶段一还可以再优化的,因为后面我采用了阶段二的方法,就没对阶段一的方法深入优化了。阶段一中的JOIN速度同样有优化空间。下面我在阶段一的代码上增加几行代码对JOIN做一下优化,给出一种即使不硬编码,也能在大约800ms内解出100万输入行的代码(也就是说是否硬编码差距就200ms左右)

SQL代码

WITH RECURSIVEoperations(op) AS (VALUES ROW(1), ROW(2), ROW(3), ROW(4), ROW(5), ROW(6)),numbers(val, enc) AS (VALUES ROW(1, 2), ROW(2, 3), ROW(3, 5), ROW(4, 7), ROW(5, 11), ROW(6, 13), ROW(7, 17), ROW(8, 19), ROW(9, 23), ROW(10, 29)),reverse_combinations1(enc, val, rst) AS (SELECT enc, val, 24e0 FROM numbers),reverse_combinations1_solution(enc, rst, solution) AS (SELECTenc,CASE opWHEN 1 THEN val + rstWHEN 2 THEN val * rstWHEN 3 THEN val - rstWHEN 4 THEN rst - valWHEN 5 THEN val / rstWHEN 6 THEN rst / valEND,CASE opWHEN 1 THEN (12 << 4) | valWHEN 2 THEN (14 << 4) | valWHEN 3 THEN (val << 4) | 12WHEN 4 THEN (11 << 4) | valWHEN 5 THEN (val << 4) | 14WHEN 6 THEN (13 << 4) | valENDFROM reverse_combinations1 CROSS JOIN operations),reverse_combinations1_solution_faster AS (SELECT DISTINCT enc, rst, solution FROM reverse_combinations1_solution),reverse_combinations2(enc, val, rst, solution) AS (SELECT t1.enc * t2.enc, val, rst, solution FROM reverse_combinations1_solution_faster t1 CROSS JOIN numbers t2),reverse_combinations2_solution(enc, rst, solution) AS (SELECTenc,CASE opWHEN 1 THEN val + rstWHEN 2 THEN val * rstWHEN 3 THEN val - rstWHEN 4 THEN rst - valWHEN 5 THEN val / rstWHEN 6 THEN rst / valEND,CASE opWHEN 1 THEN (12 << 4) | val | (solution << 8)WHEN 2 THEN (14 << 4) | val | (solution << 8)WHEN 3 THEN (val << 4) | 12 | (solution << 8)WHEN 4 THEN (11 << 4) | val | (solution << 8)WHEN 5 THEN (val << 4) | 14 | (solution << 8)WHEN 6 THEN (13 << 4) | val | (solution << 8)ENDFROM reverse_combinations2 CROSS JOIN operations),reverse_combinations2_solution_faster2x AS (SELECT DISTINCT enc, rst, solution FROM reverse_combinations2_solution),reverse_combinations3(enc, val, rst, solution) AS (SELECT t1.enc * t2.enc, val, rst, solution FROM reverse_combinations2_solution_faster2x t1 CROSS JOIN numbers t2),reverse_combinations3_solution(enc, rst, solution) AS (SELECTenc,CASE opWHEN 1 THEN val + rstWHEN 2 THEN val * rstWHEN 3 THEN val - rstWHEN 4 THEN rst - valWHEN 5 THEN val / rstWHEN 6 THEN rst / valEND,CASE opWHEN 1 THEN (12 << 4) | val | (solution << 8)WHEN 2 THEN (14 << 4) | val | (solution << 8)WHEN 3 THEN (val << 4) | 12 | (solution << 8)WHEN 4 THEN (11 << 4) | val | (solution << 8)WHEN 5 THEN (val << 4) | 14 | (solution << 8)WHEN 6 THEN (13 << 4) | val | (solution << 8)ENDFROM reverse_combinations3 CROSS JOIN operations),reverse_combinations_solution(enc, solution) AS (SELECTenc *CASE ROUND(rst)WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END,ROUND(rst) | solution << 8FROM reverse_combinations3_solution WHERE (ROUND(rst) BETWEEN 1 AND 10) AND ABS(ROUND(rst) - rst) < 0.000001),reverse_combinations_solution_distinct(enc, solution) AS (SELECT enc, ANY_VALUE(solution) FROM reverse_combinations_solution GROUP BY enc),reverse_format_solution(enc, expr, solution) AS (SELECT enc, CAST((solution & 0x0F) AS CHAR), solution >> 8 FROM reverse_combinations_solution_distinctUNION ALLSELECT enc,CASE (solution & 0xF0) >> 4WHEN 11 THEN CONCAT('(', expr, '+', solution & 0x0F, ')')WHEN 12 THEN CONCAT('(', expr, '-', solution & 0x0F, ')')WHEN 13 THEN CONCAT('(', expr, '*', solution & 0x0F, ')')WHEN 14 THEN CONCAT('(', expr, '/', solution & 0x0F, ')')ELSECASE solution & 0x0FWHEN 12 THEN CONCAT('(', (solution & 0xF0) >> 4, '-', expr, ')')WHEN 14 THEN CONCAT('(', (solution & 0xF0) >> 4, '/', expr, ')')ENDEND,solution >> 8FROM reverse_format_solution WHERE solution > 0),reverse_solution(enc, expr) AS (SELECT enc, expr FROM reverse_format_solution WHERE solution = 0),combinations2(enc, c1, c2) AS (SELECT t1.enc * t2.enc, CAST(t1.val AS DOUBLE), CAST(t2.val AS DOUBLE)FROM numbers t1JOIN numbers t2 ON t1.val <= t2.val),combinations2_solution(enc, rst, expr) AS (SELECTenc,CASE opWHEN 1 THEN c1 + c2WHEN 2 THEN c1 * c2WHEN 3 THEN c1 - c2WHEN 4 THEN c2 - c1WHEN 5 THEN c1 / c2WHEN 6 THEN c2 / c1END,CASE opWHEN 1 THEN CONCAT('(', c1, '+', c2, ')')WHEN 2 THEN CONCAT('(', c1, '*', c2, ')')WHEN 3 THEN CONCAT('(', c1, '-', c2, ')')WHEN 4 THEN CONCAT('(', c2, '-', c1, ')')WHEN 5 THEN CONCAT('(', c1, '/', c2, ')')WHEN 6 THEN CONCAT('(', c2, '/', c1, ')')ENDFROM combinations2 CROSS JOIN operations),combinations2_solution_faster7x AS (SELECT DISTINCT enc, rst, expr FROM combinations2_solution),combinations4(enc1, enc2, rst1, rst2, expr1, expr2) AS (SELECT t1.enc, t2.enc, t1.rst, t2.rst, t1.expr, t2.exprFROM combinations2_solution_faster7x t1JOIN combinations2_solution_faster7x t2 ON t1.enc <= t2.enc),combinations4_faster2x AS (SELECT DISTINCT enc1, enc2, rst1, rst2, expr1, expr2 FROM combinations4),combinations4_solution(enc, rst, expr) AS (SELECTenc1 * enc2,CASE opWHEN 1 THEN rst1 + rst2WHEN 2 THEN rst1 * rst2WHEN 3 THEN rst1 - rst2WHEN 4 THEN rst2 - rst1WHEN 5 THEN rst1 / rst2WHEN 6 THEN rst2 / rst1END,CASE opWHEN 1 THEN CONCAT(expr1, '+', expr2)WHEN 2 THEN CONCAT(expr1, '*', expr2)WHEN 3 THEN CONCAT(expr1, '-', expr2)WHEN 4 THEN CONCAT(expr2, '-', expr1)WHEN 5 THEN CONCAT(expr1, '/', expr2)WHEN 6 THEN CONCAT(expr2, '/', expr1)ENDFROM combinations4_faster2x CROSS JOIN operations),solution(enc, expr) AS (SELECT enc, ANY_VALUE(expr) FROM combinations4_solution WHERE ABS(rst - 24) < 0.000001 GROUP BY enc),lookup_table(enc, result) AS (SELECT enc, ANY_VALUE(expr) FROM (SELECT enc, expr FROM solutionUNION ALLSELECT enc, expr FROM reverse_solution) t1 GROUP BY enc),json_agg(dat) AS (SELECT JSON_ARRAYAGG(JSON_OBJECT('enc', enc, 'result', result)) FROM lookup_table),json_map(enc, result) AS (SELECT enc, result FROM json_agg, JSON_TABLE(json_agg.dat, '$[*]' COLUMNS(enc INT PATH '$.enc', result CHAR(16) PATH '$.result')) t),lookup_table_faster AS (SELECT enc, ANY_VALUE(result) result FROM json_map GROUP BY enc)SELECT id, c1, c2, c3, c4, resultFROM poker24.cardsLEFT JOIN lookup_table_faster ON enc=CASE c1WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c2WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c3WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END *CASE c4WHEN 1 THEN 2WHEN 2 THEN 3WHEN 3 THEN 5WHEN 4 THEN 7WHEN 5 THEN 11WHEN 6 THEN 13WHEN 7 THEN 17WHEN 8 THEN 19WHEN 9 THEN 23WHEN 10 THEN 29END

总结一下

非常感谢主办方玖章算术举行的趣味比赛,让我们在工作之余,可以有机会动动脑子,学学东西,跟业界同行有一些学习交流的机会。感谢评委老师们在答辩过程中的指点。感谢一起参加比赛的选手们的精彩分享。在这个过程中,真的学到了不少东西,对SQL也有了更多理解。

参赛完整SQL

WITH RECURSIVE lookup_table(enc,result,dat) AS(    SELECT 0,           'err_placeholder',           UNCOMPRESS(FROM_BASE64('ICcAAHicTVpbkiMhDLvOTCZd4WUD97/YWpIhWzUf0zTY4Ics06nW3j8/9a/+xt9rvav5+8df7ffFwXcr4/0z8e6n8bktzH/F/Ib5bcb8/dz3fcT7Wv6ugDrK+2e8+hXY4tkosPPZy9mA/756CChHweTziucV6/9+aqh5D8zff1ee4X0tD5+woG4/Asfva7x7uTs2PvvACccViBPMhzPw3npYZGGtFPgY54QD81c9FnvVEjreY8UEe9mvZLxtxgQ7Av09YZIJ5RK4uus9N7zejg04Tq/3ey2c2H8/acHviV47rBQnnHcLM/xWwsjYpEbW71+4sTms3o5b6g6ZjV4xWr3DCH/3fS9+3s+HboSG9hw3jwr5mPq3f1/tba3R6l8FFm7oVCi31nIWdFq90+39KtzlKOgwkmH+pJv53ma6/cVJb8f8Hc+P3q+Zbm8vub3t2OGg2zhh+D0B3W7D5fYUOHGicDse8H7CQuM8r/d2BjaF4X1tFXEEden3CRvL75S4bNGvkhBuqjCSHI9lIcKGZryko5pkwm0Wlg03YVe1hB3/YiLWlGv5iAg4vzfFqzYWA2OFGj8DIXXucXbKeGlNtsiQfWLNhP/D3vM3lHxaKO4MOuidGSA4vwawkbbtnl9B1ypMpBEGXahpWLMicuVkhtXPQvI0rWGYMAwYJh3P/Bee62+zGyYdJnO9fw46LLthwveb7xdOFqERyc843M9VUIdloPRHgTL2FUl8mIgkIx5wxY5teqRerPiMX6YfdY7ws0Qylvk/VoXBvVIptwSRrXQpHd9tYMS5cSZgZQArODrtW6DGzj7DmiY1rxMcnRuJ4EASSAizQtAhIUy7eXYSrh/MI+2cA/seX8HReX6pUXC0xQPThgKD1lNqRljfPPCHM5hsu1+pCo5Om8hI6/cJBOmznOCg64wpvygkTIWRtq/YzaR37i3Kify732tU2uAPKSjT+kKMjfRGJGqZ6zh0KO0mgt0144kZjsCVRzVjMUHwvzzamKnh0ZHo0NZo16Na43scNSYHlobA+bEIGw44sltqNGMjdRdlmKKfMAslcvEY2Fmq0Zru93gO7/SyBVwjYaYPJKafAWD1EnSN9Lk1WERq5OJRBkFkXAcS0KfsASE25jgz6AsrMMk6UqNsVRxPDmVh3L2r9m9YXpVrzvF1F+3W3LM8fizkWIS1kNlOVJsJeu2YaRbCZJjFYKenRtByxF7HKoMelBDGrI2u7VqayQ1GCKtYpsZixQihfvXUImi1tOTy0s5OptB40XAq9oWLNn2IJQr07VWxYwePW1W1/Fs3+6vDVpum0sjwNBWHFJVW2td6DIfRie3+nIP7aC3hyj8r4GrS5KHe8+B7SQrP6S/VFFnYj/trW1W+i+xlpoQ3F4M15cQxaoeNN0/hCWpN4cpnTuqTmcNTSNnsSh0N0Yqdpt9UJv3BgbTJ+d0S03ZRnUYGK+yWh6ltsY6lZeWhqON+NqDC1XyuK3trA4wfyV7KZi9+DrcSjxXOD591ODscB1Qp1G9Qjvvc9mRQNpKmFkm1WWTb78Nnqx0WvfO91Xi/OTmWvOfqt/hLYLNTLfncq7GOt6yWY1sqhNConovvPy1J1fT7PFU97XDp9uAABSdStdSJejEBbv+l1ECkSmSUihE8rB/U44pV92HTKXLWA3oSWWkVcktVyzH2YRZDZmzzgp7WFFg2qdWnMT6nmFM8kfQ4bDXFk14UsiqZgOXGI3zojdiUKGuIwAxLc4M1GxzgHzjEqXcveiyngDk1uozbYvn0DSFYI6m976/THBaIhgZT5iOrh+JdZjK2JoCOWkgrf86U3mATGYkgElL7MRIiBq7eybj/yNPeXkpH+Dz3PNN8f/FCETONVVgRERHQ7NggoqC/t94/J2KiVt4BhkwdzQ4R73TwbEckROyggViStATZ8Z79zlBFrnaFkosHktgh4ykUkQuG8TSx7Y3QHmcgKvJA7O9YEvQBIdHL+KrNOMIURQ2ltoopdoSA2SC8RR8RGJFQ2Cr4Zhq1z20H8XmWwZ3ZI5bCpLTv8VSRmZaS6tzaZBYtmQjVaSwTQcwwMje7mCw9HVIndzI5sLD5lRyrodGF0QCaL1lg9m3iaX8KwCh62Mk6eqJGm6XilwZWc7uAKWdtYgDxkgO1lGIXsDstG1RGuPD0mzylbZKKljw6WPA8sSWatevFjiEyuvfhFBh9t7n7IUR0YTCIemKaMkbznlqy6wpmpjRmov+hv0ceqPRLyAaeiFoP5k4nnDx8IrnpQGJ5mUvctzJnHDwJarYPtZYQh15tnmARvds8fTpneBzn7JXUeu46r5elp7gAZhKlAk6J+aoRC1ZcDUZTaRyvxOhrgpl5TitxhI1X6JnJ+FrWagPYpZ+VHbWWfRytkVHKAd4/Yk3koTtFf2Bs2jx4HkTB3hmZvlTngr/pcmB1ohcyKtvYYu3gdQgCyzO7cKw+djb4nmRLORHZW8ljLb0UhVx6tCTENlUjy2iIzNrW6et560BxVl0WxSn6tUs/nG3z4N4SKLksqxSLMycRCaJMtXoYgSW+qEA/fCYqtUJ3PXZzMMqOcdbHLmTElqqC6Y93a0EsKzOBeEGS5r0n28oCV+kJcTQVp2jlKFhilJe2VVo8bRYljdU1eRxrWsvyOr+SCiJ1JZOj38tAkGFzz+bJgm2p4CzSRpyseFd2+impUer62SRrU1Syuf8rQqyI1cfE6ZLvEUMr9YWVJoNohnUHTLkeVk4Zl1VfkNdYFUdRRiW7Q1pGt1rv8bSHVhRs63PKaRiFwf+wmLKFhRFuhrDE9lLhOWWIRlapMgIhibU7IGt+zwcVuIJs+26LZT3AgEUCdZMXE2ue56erBE4WK91kdAalnRsCUL7wQLPThmvgFHPJWGA0ie5RJXhXShmnFGNNJYUclDqoZmtjsUK1uLHii8H1p5PFZi2mVFzdkQLkZUbMGKVZdseplwNZeWNVoKeE2tlHdDeiqp1Z2d/e27fQYsbcohHEGVpkcO+RIj0vf8zat9Biq16/VnVYZA5ahBlCGXu0/wot9bQ0wCTlme9VsEbBqTVzXlYM8783jreCdzysxwCZ3U5B76fvmf8VVpq+U1NWVo64/0eVoCASj4V18JIUBSGQiQPP8U+v63IljEZ775YXAPLPIJmgDPgoypv35EqPnB6N7bd8Z13t12OUaiz6dqSiXx6mKpqRM0lzlq4zcJzFdkI+3YzpWsUuCH1cFMBnB/k4sJy0RiWRAVmGWzasOk/tddutS65JVRxrsL/HSLYqU0dCX9FdLGte0UFV7eL8oAuskeBlXVRCLGnjs9pKq+m5kPRhToz+9Rx3Ft2a2yEiZHnBiJYd4mHaJDu0lVcZDAoaBLcDvP4IBs4NiWhoUSNdlhgEP/rOZYdqaI6PYQd4KbiVqR3S1NI12f+tR5WbkGLFTnXQsknDJnxq2VabmIUPk4b6RB4e4tDSqPUEPd28nHRfX99v5Xya/9Ew24my2aPC13mfPXrGs2fkVS8MLP87aV1l/p2Vj1viSSQn77QXqXpI8uxdooXfN7W1TAyZFUwm6Y19BA197rU7I1JDutheg3bjXReRJzySdmMs68NVX9dK0EBO/0Uf5rsNh+yOyk9mBH3DaIEsj/TKoAXwIBITGKxW/WcGcLH3r7scz52zFF83J9RGzqo4iV3msrH9ZgndZE7I2Se0J7+NyJkqcky4PhioYc1Oqop7RqUJGcJitofpBDRU//sJzC5NLQiLKiYF0/Fvf7EeYv/KjFdR5bSyvo0JbTddfRWGMBHJ4zPTKSKM9uyI1oqSx/vfIPS44SaB/oyE1KGLGbxUY2KrX27PJW51HqzjwFy8GdiYwp5270EakCA7AHXtXlpA13uSXpueSPKqH8o7hHSljXrwgXqqiWPprlPdc6ulny+SDuSpEZ+XG2rZIsPK7NdQ1InKFnowYoJhGS9aBKKLggKMLlvkKrTZX7YoQdPXZYuaFLL7KTCLI9E/7XuHQ9mjNlAumAj5GX17GK3DrDKRcQOV/DlgJkSZvmZ1NYkJkOgrCzqFcUYIB+uybtxFMYX6ZQ/GbXdyU6dtUT5BcuttDGXITX4n9USaFlSmH6ShnIA6kTtihrRFYb8dxZTZeLm0ElgHySS8r6DS55u5XRdDdnvZObdCZDFEkOc+DlHV8Ucb4u8EVlo7mGvn1c9nn4+bUSL2oVMqT8G5LW+Zrr7gt2xRPc8bLXnYn6Hvx0qtDZDnlViLkSlPwmT5zWj0JM9c9mEENPotsZaG49WYlAnEjI2rrjC4aozF/p6i88NRFNF6hoi+fU+fB2e4RyuVjSBpxPkIH6X14AwnoddWKO+zLuphr1+c4VicZdMCiazBuJbu53AWNeWAPvXtI7HPGm8dVBEm7W2m3v6jfaNzjmUSDU/pI3NXnjJ1YAhet0xF/MEwnIbBK9JNJA/LNV1wjuzQZliq3w6NgRENInw+jsJozSMudck8hJm4Gwh+0/9rYZgJEVLr21rthBlYOdM1ogh3+aWfEWQWSg6hIPPO+IMR3QbEQ8aYz68cRFqExlo3xriqR1m64aORXXg1QjkMH4vK9e2skcZRYX1d0euzUILWvBiDkHl7sO6a2BB2wjl8lHKxGqZCE1DuMoYMOOf0+h2Db4CProz1j+vzW+ATwCDzBTu3LlcR0ZAvkcHwy8Z9Ibuit3Vdjgnn9QkrGgaJViDGiPMLw8rvNFhmvKYQhjAVLfpGZZllaHo0u+cqHJHiUbx4zwbFHxwkjDLNx8xeXvC0Le/esAyRgsvg0vxGClLW2AbUeQgEN7Vb3RfYlMTR5yT6WSbxik5HKWQZv1HVilppBjBF1QCfpqoB+bpMstl4ETQPkPEKjFGW9zVRmqK49n4zkiS1gp/sYwkFfzTVc/4X/Jtsdpl/72f+wNzqHP1YniNBNwEdTg6+w/fBY2ZVLsurGHKm8s6rFsdvfVjy8jwMBq8MPrF5aAiTMiG5QraJQln/u32BpBo7b/24LClvCd7UD1TJaZEk895LYicgEJOfPhCjFwScNyKTmwejQtezvN69SsPajHdZQr8siiMSaYFLVIPOq+yrk5tG+XXvp4laMBiugUY6d92fMgW1Vy1LKMfvHILn/XfHwtKLPm26zj+/P3uqvDTUmLaHkiq3aH+TbQ8vDhUborjR+HheQWEzKS946EnLJYH/ALZfNLo='))     UNION ALL    SELECT CAST(SUBSTRING_INDEX(dat,',',1) AS SIGNED),           SUBSTRING_INDEX(SUBSTRING_INDEX(dat,',',2),',',-1),           SUBSTRING(dat,LENGTH(SUBSTRING_INDEX(dat,',',2))+2)      FROM lookup_table     WHERE LENGTH(dat)>0    ),    lookup_table_faster5x AS (      SELECT enc,ANY_VALUE(result) AS result FROM lookup_table GROUP BY enc    )SELECT id,       c1,       c2,       c3,       c4,       result  FROM poker24.cards  LEFT JOIN lookup_table_faster5x ON enc=CASE c1         WHEN 1 THEN 2         WHEN 2 THEN 3         WHEN 3 THEN 5         WHEN 4 THEN 7         WHEN 5 THEN 11         WHEN 6 THEN 13         WHEN 7 THEN 17         WHEN 8 THEN 19         WHEN 9 THEN 23         WHEN 10 THEN 29       END *CASE c2         WHEN 1 THEN 2         WHEN 2 THEN 3         WHEN 3 THEN 5         WHEN 4 THEN 7         WHEN 5 THEN 11         WHEN 6 THEN 13         WHEN 7 THEN 17         WHEN 8 THEN 19         WHEN 9 THEN 23         WHEN 10 THEN 29       END *CASE c3         WHEN 1 THEN 2         WHEN 2 THEN 3         WHEN 3 THEN 5         WHEN 4 THEN 7         WHEN 5 THEN 11         WHEN 6 THEN 13         WHEN 7 THEN 17         WHEN 8 THEN 19         WHEN 9 THEN 23         WHEN 10 THEN 29       END *CASE c4         WHEN 1 THEN 2         WHEN 2 THEN 3         WHEN 3 THEN 5         WHEN 4 THEN 7         WHEN 5 THEN 11         WHEN 6 THEN 13         WHEN 7 THEN 17         WHEN 8 THEN 19         WHEN 9 THEN 23         WHEN 10 THEN 29       END

数据库编程大赛下一次再聚!

感谢大家对本次《数据库编程大赛》的关注和支持,欢迎加入技术交流群,更多精彩活动不断,我们下次再相聚!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/612543.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS 高频面试题

JS 的数据类型有哪些&#xff0c;有什么区别 基本数据类型&#xff08;Undefined、Null、Boolean、Number、String、Symbol&#xff09; 引用数据类型&#xff08;对象、数组和函数&#xff09; 区别&#xff1a; 原始数据类型直接存储在栈&#xff08;stack&#xff09;中的简…

【亲测有效】Win11 卸载MySQL5.7以及安装MySQL8.0.35

目录 一、卸载原来本地的mysql5.7 1.mysql服务部分 1.1停止mysql服务 1.2删除mysql服务 2.卸载 MySQL程序 3.残余文件的清理 3.1删除mysql安装的目录 3.2删除mysql数据存放的目录 3.3删除mysql自定义目录 4.清理注册表 5.删除环境变量配置 二、安装mysql8.0.35 1.…

【Spring Boot】SpringMVC入门

1.什么是springMVC MVC就是把一个项目分成了三部分&#xff1a; MVC是一种思想。Spring进行了实现,称为Spring MVC。SpringBoot是创建SpringMVC项目的一种方式而已。springMVC对于MVC做出了一些改变&#xff1a; 当前阶段,MVC的概念又发生了一些变化,后端开发人员不涉及前端页…

众和策略股市行情分析:了解散户的典型特征

散户特色如下&#xff1a; 1、出资规模小&#xff1a;散户的出资规模一般比较小&#xff0c;资金量有限&#xff0c;无法对商场发生显著的影响。资金量较小的一起&#xff0c;其对危险的承受能力也相对较弱。 2、缺少危险意识&#xff1a;散户往往缺少危险意识&#xff0c;没…

2024年网络工程师10大必备软件,最新安装包分享

功夫再高&#xff0c;也怕菜刀。作为网络工程师&#xff0c;我们手中的菜刀是什么&#xff1f; 以下10大网工必备软件都已整理好安装包&#xff0c;需要的朋友可以在文末获取。 1、Cisco Packet Tracer&#xff08;思科模拟器&#xff09; Cisco Packet Tracer 是由Cisco公司发…

详解JavaScript中的WeakMap和WeakSet

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ ✨ 前言 内存管理一直是JavaScript这门语言中的难点和痛点。由于其自动垃圾回收机制的限制,在某些场…

HTTPS详解及openssl简单使用

OpenSSL 中文手册 | OpenSSL 中文网 本文介绍https传输协议中涉及的概念&#xff0c;流程&#xff0c;算法&#xff0c;如何实现等相关内容。 HTTP传输过程 HTTP 之所以被 HTTPS 取代&#xff0c;最大的原因就是不安全&#xff0c;至于为什么不安全&#xff0c;看了下面这张图…

如何通过 Prompt 优化大模型 Text2SQL 的效果

前言 在上篇文章中「大模型LLM在Text2SQL上的应用实践」介绍了基于SQLDatabaseChain的Text2SQL实践&#xff0c;但对于逻辑复杂的查询在稳定性、可靠性、安全性方面可能无法达到预期&#xff0c;比如输出幻觉、数据安全、用户输入错误等问题。 本文将从以下4个方面探讨通过Pr…

Python办公自动化 – 操作NoSQL数据库和自动化图像识别

Python办公自动化 – 操作NoSQL数据库和自动化图像识别 以下是往期的文章目录&#xff0c;需要可以查看哦。 Python办公自动化 – Excel和Word的操作运用 Python办公自动化 – Python发送电子邮件和Outlook的集成 Python办公自动化 – 对PDF文档和PPT文档的处理 Python办公自动…

前端-基础 表格标签 - 相关属性详解

目录 相关属性 &#xff1a; align 属性 &#xff1a; border 属性 &#xff1a; cellpadding 属性 &#xff1a; cellspacing 属性 &#xff1a; width 属性 &#xff1a; height 属性 &#xff1a; 首先&#xff0c;需要声明的是 表格标签这部分属性&…

Hive基础题-1

别看我&#xff0c;不看答案我也不会写 正因为不会写&#xff0c;所以才要每天一练 本地hive练习题 SET hive.exec.mode.local.autotrue; -- 默认 false SET hive.exec.mode.local.auto.inputbytes.max50000000; SET hive.exec.mode.local.auto.input.files.max5; -- 默认 4# …

Hotspot源码解析-第十七章-虚拟机万物创建(三)

17.4 Java堆空间内存分配 分配Java堆内存前&#xff0c;我们先通过两图来了解下C堆、Java堆、内核空间、native本地空间的关系。 1、从图17-1来看&#xff0c;Java堆的分配其实就是从Java进程运行时堆中选中一块内存区域来映射 2、从图17-2&#xff0c;可以看中各内存空间的…

thinkphp学习07-数据库的数据查询

单数据查询 单条数据查询&#xff0c;一般是一维数组 Db::table()中 table 必须指定完整数据表&#xff08;包括前缀&#xff09;&#xff0c;如果配置了表前缀&#xff0c;Db::name()中可以忽略 如果希望只查询一条数据&#xff0c;可以使用 find()方法&#xff0c;需指定 wh…

Django 框架添加管理员,完成对普通用户信息管理

前情回顾&#xff1a;Django框架 完成用户登录注册 文章目录 1.创建管理员2.完善管理员功能2.1增加管理员登录功能2.2完善展示用户信息功能2.3完善修改用户信息功能2.4完善删除用户信息功能 1.创建管理员 一般管理员都是直接指定&#xff0c;不开放页面注册&#xff0c;可以直…

Mermaid 教程

Mermaid 教程 Mermaid 介绍 Mermaid 是一个用于生成流程图、时序图、甘特图等图表的 JavaScript 库。它使用类似于 Markdown 的文本语法&#xff0c;使得创建图表变得简单直观。以下是一个简单的 Mermaid 教程&#xff0c;介绍如何使用 Mermaid 创建流程图、时序图和甘特图。…

wxWidgets实战:使用mpWindow绘制阻抗曲线

选择模型时&#xff0c;需要查看model的谐振频率&#xff0c;因此需要根据s2p文件绘制一张阻抗曲线。 如下图所示&#xff1a; mpWindow 左侧使用mpWindow&#xff0c;右侧使用什么&#xff1f; wxFreeChart https://forums.wxwidgets.org/viewtopic.php?t44928 https://…

【MMC子系统】四、MMC控制器驱动层

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强企业&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

Keil编译生成的bin文件自动以版本号命名

Keil编译程序生成bin文件时&#xff0c;如何自动以版本号命名bin文件 一、目的二、方法三、实现过程1、脚本形式2、可执行文件形式 一、目的 Keil编译程序时&#xff0c;生成的Hex/Bin文件名字是根据Keil中工程配置里定的名字命名。通常代码里会有一个字段专门用来定义软件版本…

权限维持篇

一、Windows 1、 不死马权限维持 1.1 概述 <?php ignore_user_abort(); //关掉浏览器&#xff0c;PHP脚本也可以继续执行. set_time_limit(0);//通过set_time_limit(0)可以让程序无限制的执行下去 $interval 5; // 每隔*秒运行 do { $filename test.php; if(file_exi…

vue3.2引用unplugin-vue-components插入,解放开发中import组件

目录 前言引用unplugin-vue-components插件的优缺点优点缺点 unplugin-vue-components插件引入安装插件配置vite配置更新TypeScript配置使用代码位置 总结Q&A 前言 unplugin-vue-components是一个用于Vue.js项目的插件&#xff0c;特别适用于Vite和Webpack构建工具。它的主…