如何让数据库中的Python跑的更快-VLDB22-YeSQL文章阅读
文章全名:YeSQL: “You extend SQL” with Rich and Highly Performant User-Defined Functions in Relational Databases
关键词:Python,DataBase UDF,JIT
作者来自希腊大学与雅典娜研究中心,VLDB 2022的论文
之前怼着YeSQL: Rich User-Defined Functions without the Overhead看了老半天,没看出啥名堂😅
那篇是Demo,这篇才是正文
相关工作
编译器(Compiler)
GraalPython:在Python中运行JVM
Numba:使用JIT加速Python Numpy运行
Pyston(该项目目前已停止维护):使用LLVM JIT加速Python
转译器(Transpilers)
Cython: Python转C
Nuitka: Python转C++
数据处理系统(Data Process System)
Tuplex: Brown University SIGMOD2021的工作
Pyspark:大名鼎鼎的Pyspark,无需多言
MonetDB(Python UDF):一个荷兰公司开发的列式数据库,在Andy的课上听到过
UDF实现方案
-
将 UDF 转换为 SQL
-
优点:可以实现全局UDF查询优化
-
缺点:针对库/框架,很难支持完全成熟的语言
-
-
将 UDF(和相关操作)翻译成通用中间表示法(IR)
-
优点高级融合、循环融合、传统查询优化在一定程度上适用
-
缺点:针对库/框架,很难支持完全成熟的语言
-
-
将 UDF 嵌入数据引擎
-
优点 现有任意代码、融合/循环融合、矢量化、函数内联等优化、JIT/LLVM 编译等性能提升工具
-
缺点:查询优化比较棘手(仍然可行!);需要对用户代码进行分析、成本预测等
-
而嵌入引擎的又分成三个流派:1.直接SQL运行 2.将UDF通过JIT预编译 3.将Query通过JIT预编译
特性Feature
架构方案
文章将用户分为两类:Application Users(使用数据库的普通用户)和UDF developers(UDF编写人员)
一个名为CFM(Connection and Function Manager)的组件会将UDF进行预编译
如果是Server数据库(文章以MonetDB为例),就预编译后的UDF送进DBMS的线程内嵌库中(in-process embedded library)备用——对应MonetDB就是通过其CFFI连接Monet DB的C API进行调用
如果是嵌入式数据库(文章以SQlite为例),就通过Python CFFI包装SQlite API进行调用
YeSQL实现了UDF所应当具有的scalar, aggregate, table functions等功能
Python与C++代码量总计66K行,目前支持150多种UDF
UDF使用比pg-Python快68倍(回过头来看,这个比较其实不太公平😅MonetDB是列存,读取速度肯定要比pg快)
函数概览
使用了不少Python语言的内置函数(反正PyPy是JIT运行,性能不会差)
Join和Filter还是由数据库自己的执行引擎实现
举了两个SQL语句样例,解释其UDF运行的逻辑(不在这里赘述)
测试数据来源:zillow(美国房地产数据),flights(U.S. Department of Transportation Bureau of Transportation Statistics. 2020)
性能增强方案
核心在于如何避免SQL解析和Python的不匹配(mismatch)
这样的不匹配会导致两种开销:
(1)上下文切换开销,(Example:Python如果要频繁调用DBMS的API,就会有很大的调用开销)
(2)类型转换开销,涉及到类型的包装/解包,编码/解码
针对这两个问题,有5种应对方案
- Tracing JIT Compilation(追踪即时编译)
- 无缝与DBMS衔接
- UDF融合(Fusion)
- 并行化
- 状态化UDF
Tracing JIT Compilation
使用PyPy就自带Tracing JIT Compilation,这点不需要在工程上特别实现
Tracing JIT(即时追踪编译)是一种动态代码优化技术,专注于识别并优化程序中最常执行的路径,也称为“热路径”。它的特点是不会直接编译整个函数或方法,而是动态追踪并记录代码的执行过程,锁定这些频繁执行的路径并将它们编译成高效的机器码。这样,在这些路径再次执行时,程序可以直接运行优化后的代码,显著提升运行速度。
Tracing JIT的工作过程:
追踪阶段:Tracing JIT 首先解释执行代码,动态追踪代码的执行流,并找到一些频繁运行的路径或循环。这种追踪通常在检测到某段代码多次执行时启动。
记录执行路径:在追踪热路径时,JIT 会记录下路径中的每个操作、变量的值和类型等信息,形成一条“路径”。
编译热路径:一旦锁定热路径,JIT 会将该路径编译为高效的机器码。因为仅编译了热点代码路径,编译过程可以更快、更高效,且编译器可以针对该路径进行深入优化。
优化后的执行:当程序再次进入热路径时,JIT 会直接运行已经编译好的机器码,而不再重新解释执行,从而大幅提升执行效率。
回退与去优化:如果发现新的代码执行情况不符合之前的路径假设(比如类型变化),JIT 会“去优化”(deoptimization),回到解释器模式并可能重新追踪新的路径。
示例
PyPy(针对Python)和LuaJIT(针对Lua)是典型的Tracing JIT实现。它们通过锁定并优化高频路径,将这些解释性语言的性能大幅提升。
Tracing JIT 的主要优势在于,它能够精准地将编译工作集中在最耗时的路径上,实现高效的代码执行。这对于带有大量循环的程序尤其有效,因为这些循环的执行频率高、路径固定,能获得显著的性能提升。
这里跑个题:有意思的点在于,Chrome V8虽然也能热路径优化,但却属于Method-based JIT
Tracing JIT 适合优化具有稳定循环和执行路径的程序,而 V8 则通过函数级别的编译方式,适应 JavaScript 的动态特性,更加灵活且能覆盖整个函数的优化需求。因此,尽管 V8 和 Tracing JIT 都会进行去优化和类型假设,但 V8 不属于 Tracing JIT,因为它不聚焦于追踪特定路径,而是优化整个方法。
Java的Hotspot其实也具备Tracing JIT Compilation的特性,也不属于Tracing JIT Compilation的范畴
因此,虽然 HotSpot JVM 有类似 Tracing JIT 的“热点检测”和去优化机制,但它并不属于 Tracing JIT,而是更倾向于方法级别的 JIT 编译,通过分层编译和方法优化来提升 Java 程序的整体性能。
无缝与DBMS衔接
可以理解为:使用C API,当然你想的话直接开发个DBMS,把你开发的UDF特性写进去也不是不行😆
UDF融合(Fusion)
这里上两张作者团队在SEBD2023(PDF下载链接放后面的参考资料中)的PPT,看起来简单易懂😁这不就是内联函数么
并行化
Pypy虽然也有GIL锁,但在CFFI转换期间GIL会懒惰释放,所以并行化不会有问题,不需要在工程上特别实现,Pass
状态化UDF
用空间换时间的方案:存储函数的上下文,从而加速调用速度
这里放一张我做的组会PPT
虽然这名字有点唬人😂但本质就是函数上下文存储
Evaluation评估
SEBD2023的PPT的34-37页讲了些基本的实验细节
但跟主要的内容还是对于性能增强方案的评估
这里我不得不提到这张图,虽然之前Demo里也有这张图,但直到本文才对这张图进行了解释
这其中有的方案,按特定顺序可以实现1+1>2的效果
比如:
在 JIT 之前应用Parallelism不会产生很好的效果,而且在Parallelism和JIT前实现UDF Fusion就可能失去动态优化
因此建议执行路线是UDF Fusion -> JIT -> Parallelism
在JIT之前矢量化(Vectorization)会更好,可以减少动态跟踪所需的指令
Tracing JIT Compilation
实验结果表明:PyPy执行UDF的速度是CPython的3倍,Cython的1.7倍
Nuitka和Numba虽然也比CPython的执行分别快2.4倍于与1.9倍,但依然没有YeSQL快
Seamless integration with a DBMS
和原生SQL比较,使用80M flights数据,YeSQL会快上1.4倍
(这里图没处理好,灰色柱子是Numpy,远慢于两者)
Multithread
文章设置了一个很复杂的实验
涉及到冷/热缓存,固态/机械硬盘读取/共享内存读取
实验在列式数据库上实现
YeSQL多线程的速度是Tuplex的1.56到3.37倍
且Tuplex受缓存的影响特别大,而YeSQL则没有这个问题。
UDF Fusion
测试用的SQL语句,三个UDF函数嵌套
select extractnumber(lower(remove_small_words(text))) from texts;
UDF在处理字符串的问题上效益会更好
Parallelism
文章说多线程YeSQL相比较于单线程YeSQL有50%的提升,但真按图中显示只有33%的提升
虽然但是,原本单线程的YeSQL就比MonetDB自带的CPython与Vectorized化后的Numpy快上几倍
Stateful UDFs
基于Zillow数据衡量
这一段篇幅不大,但需要结合前边内容看
前边的方案开启了Stateful,运行只需要7秒
后面的则没有开启Stateful,运行需要14.6秒
Resource Usage
与tuplex和Pyspark对比,内存占用是三者当中最低的同时,CPU使用率要比Tuplex好
Code Review
Code: https://github.com/athenarc/YeSQL/
使用说明指南:https://athenarc.github.io/YeSQL/
运行在Pypy2.7(Note:虽然Python2已经被废弃,但Pypy2.7截止到2024.08.22还是可是维护状态)当中,Server-Base的话使用CFFI与系统交互,Embedded直接使用API(多半也是C/C++ API)
在排除了PyPy和MonetDB安装包后,项目结构目录如下:
YeSQL/
|-- README.md
|-- Specs.md
|-- YeSQL_MonetDB
| |-- cffi_wrappers
| | |-- createfuncs.sql
| | |-- libwrappedudfs.so
| | `-- udfs.h
| |-- functions
| | |-- __init__.py
| | |-- aggregate
| | | |-- __init__.py
| | | |-- date.py
| | | |-- graph.py
| | | |-- jpacks.py
| | | |-- mining.py
| | | |-- partialsort.py
| | | |-- selection.py
| | | |-- setpath.py
| | | |-- skcluster.py
| | | |-- skdimred.py
| | | |-- statistics.py
| | | |-- subgroup.py
| | | |-- text.py
| | | `-- util.py
| | |-- conf.py
| | |-- row
| | | |-- __init__.py
| | | |-- boolean.py
| | | |-- date.py
| | | |-- evals.py
| | | |-- fileops.py
| | | |-- formating.py
| | | |-- htmlops.py
| | | |-- iptools.py
| | | |-- jpacks.py
| | | |-- langtools.py
| | | |-- logparse.py
| | | |-- mathops.py
| | | |-- setpath.py
| | | |-- settings.py
| | | |-- similarity.py
| | | |-- stopwords.py
| | | |-- stringdist.py
| | | |-- termsetops.py
| | | |-- testing
| | | | `-- sales.tsv
| | | |-- text.py
| | | |-- tzconverter.py
| | | |-- util.py
| | | `-- variables.py
| | |-- setpath.py
| | |-- sqltransform.py
| | `-- vtable
| | |-- __init__.py
| | |-- cache.py
| | |-- clipboard.py
| | |-- clipout.py
| | |-- coltypes.py
| | |-- continue.py
| | |-- dirfiles.py
| | |-- examplevt.py
| | |-- exec.py
| | |-- expand.py
| | |-- file.py
| | |-- flow.py
| | |-- fromeav.py
| | |-- hidden.py
| | |-- jsonpipe.py
| | |-- mysql.py
| | |-- oaiget.py
| | |-- oracle.py
| | |-- ordered.py
| | |-- output.py
| | |-- pipe.py
| | |-- postgres.py
| | |-- queryplan.py
| | |-- range.py
| | |-- rowidvt.py
| | |-- sample.py
| | |-- setpath.py
| | |-- setschema.py
| | |-- skpredict.py
| | |-- sktrain.py
| | |-- slidingwindow.py
| | |-- sqlite.py
| | |-- stdinput.py
| | |-- testing
| | | |-- GeoIPCountryCSV.zip
| | | |-- colpref.csv
| | | |-- colpref.tsv
| | | |-- colpref.tsv.gz
| | | |-- colpref.zip
| | | |-- internalflow.sql
| | | |-- testflow.sql
| | | |-- testtable.sql
| | | `-- topflow.sql
| | |-- timeslidingwindow.py
| | |-- toeav.py
| | |-- unindexed.py
| | |-- unionalldb.py
| | |-- variables.py
| | |-- vtbase.py
| | |-- vtiterable.py
| | |-- vtout.py
| | |-- webtable.py
| | |-- whilevt.py
| | `-- xmlparse.py
| |-- functionslocal
| | |-- __init__.py
| | |-- aggregate
| | | `-- __init__.py
| | |-- row
| | | `-- __init__.py
| | `-- vtable
| | `-- __init__.py
| |-- lib
| | |-- LM
| | | |-- DisabledLMs
| | | | |-- afrikaans.lm
| | | | |-- amharic-utf.lm
| | | | |-- arabic-iso8859_6.lm
| | | | |-- arabic-windows1256.lm
| | | | |-- basque.lm
| | | | |-- breton.lm
| | | | |-- catalan.lm
| | | | |-- chinese-big5.lm
| | | | |-- chinese-gb2312.lm
| | | | |-- drents.lm
| | | | |-- esperanto.lm
| | | | |-- frisian.lm
| | | | |-- greek-iso8859-7.lm
| | | | |-- greek-windows1253.lm
| | | | |-- hebrew-iso8859_8.lm
| | | | |-- hindi.lm
| | | | |-- indonesian.lm
| | | | |-- irish.lm
| | | | |-- japanese-euc_jp.lm
| | | | |-- japanese-shift_jis.lm
| | | | |-- korean.lm
| | | | |-- malay.lm
| | | | |-- manx.lm
| | | | |-- marathi.lm
| | | | |-- middle_frisian.lm
| | | | |-- mingo.lm
| | | | |-- nepali.lm
| | | | |-- persian.lm
| | | | |-- quechua.lm
| | | | |-- rumantsch.lm
| | | | |-- sanskrit.lm
| | | | |-- scots.lm
| | | | |-- scots_gaelic.lm
| | | | |-- swahili.lm
| | | | |-- tagalog.lm
| | | | |-- tamil.lm
| | | | |-- thai.lm
| | | | |-- ukrainian-koi8_r.lm
| | | | |-- vietnamese.lm
| | | | |-- welsh.lm
| | | | `-- yiddish-utf.lm
| | | |-- albanian.lm
| | | |-- armenian.lm
| | | |-- belarus-windows1251.lm
| | | |-- bosnian.lm
| | | |-- bulgarian-iso8859_5.lm
| | | |-- croatian-ascii.lm
| | | |-- czech-iso8859_2.lm
| | | |-- danish.lm
| | | |-- dutch.lm
| | | |-- english.lm
| | | |-- estonian.lm
| | | |-- finnish.lm
| | | |-- french.lm
| | | |-- georgian.lm
| | | |-- german.lm
| | | |-- greek-utf.lm
| | | |-- hungarian.lm
| | | |-- icelandic.lm
| | | |-- italian.lm
| | | |-- latin.lm
| | | |-- latvian.lm
| | | |-- lithuanian.lm
| | | |-- norwegian.lm
| | | |-- polish.lm
| | | |-- portuguese.lm
| | | |-- romanian.lm
| | | |-- russian-iso8859_5.lm
| | | |-- russian-koi8_r.lm
| | | |-- russian-windows1251.lm
| | | |-- serbian-ascii.lm
| | | |-- slovak-ascii.lm
| | | |-- slovak-windows1250.lm
| | | |-- slovenian-ascii.lm
| | | |-- slovenian-iso8859_2.lm
| | | |-- spanish.lm
| | | |-- swedish.lm
| | | `-- turkish.lm
| | |-- TableHTMLParser.py
| | |-- __init__.py
| | |-- argsparse.py
| | |-- boolops.py
| | |-- chardet
| | | |-- __init__.py
| | | |-- big5freq.py
| | | |-- big5prober.py
| | | |-- chardistribution.py
| | | |-- charsetgroupprober.py
| | | |-- charsetprober.py
| | | |-- codingstatemachine.py
| | | |-- constants.py
| | | |-- docs
| | | | |-- css
| | | | | `-- chardet.css
| | | | |-- faq.html
| | | | |-- history.html
| | | | |-- how-it-works.html
| | | | |-- images
| | | | | |-- caution.png
| | | | | |-- important.png
| | | | | |-- note.png
| | | | | |-- permalink.gif
| | | | | |-- tip.png
| | | | | `-- warning.png
| | | | |-- index.html
| | | | |-- license.html
| | | | |-- supported-encodings.html
| | | | `-- usage.html
| | | |-- escprober.py
| | | |-- escsm.py
| | | |-- eucjpprober.py
| | | |-- euckrfreq.py
| | | |-- euckrprober.py
| | | |-- euctwfreq.py
| | | |-- euctwprober.py
| | | |-- gb2312freq.py
| | | |-- gb2312prober.py
| | | |-- hebrewprober.py
| | | |-- jisfreq.py
| | | |-- jpcntx.py
| | | |-- langbulgarianmodel.py
| | | |-- langcyrillicmodel.py
| | | |-- langgreekmodel.py
| | | |-- langhebrewmodel.py
| | | |-- langhungarianmodel.py
| | | |-- langthaimodel.py
| | | |-- latin1prober.py
| | | |-- mbcharsetprober.py
| | | |-- mbcsgroupprober.py
| | | |-- mbcssm.py
| | | |-- sbcharsetprober.py
| | | |-- sbcsgroupprober.py
| | | |-- sjisprober.py
| | | |-- test.py
| | | |-- universaldetector.py
| | | `-- utf8prober.py
| | |-- collections26.py
| | |-- colorama
| | | |-- LICENSE.txt
| | | |-- __init__.py
| | | |-- ansi.py
| | | |-- ansitowin32.py
| | | |-- initialise.py
| | | |-- win32.py
| | | `-- winterm.py
| | |-- conutils.py
| | |-- dateutil
| | | |-- LICENSE
| | | |-- __init__.py
| | | |-- easter.py
| | | |-- parser.py
| | | |-- relativedelta.py
| | | |-- rrule.py
| | | |-- tz.py
| | | |-- tzwin.py
| | | `-- zoneinfo
| | | |-- __init__.py
| | | `-- zoneinfo-2010g.tar.gz
| | |-- dsv.py
| | |-- fastavro
| | | |-- NOTICE.txt
| | | |-- PKG-INFO
| | | |-- __init__.py
| | | |-- __main__.py
| | | |-- reader.py
| | | |-- six.py
| | | `-- writer.py
| | |-- gtable.py
| | |-- gzip32.py
| | |-- gzip34.py
| | |-- htmlentities.py
| | |-- inoutparsing.py
| | |-- ipaddr.py
| | |-- iso8601.py
| | |-- iterutils.py
| | |-- jaydebeapi
| | | |-- COPYING.LESSER
| | | |-- __init__.py
| | | `-- dbapi2.py
| | |-- jdbc
| | | `-- readme.txt
| | |-- jopts.py
| | |-- jsonpath.py
| | |-- kdtree.py
| | |-- listser.py
| | |-- madcomp.py
| | |-- memoize.py
| | |-- pg8000
| | | |-- __init__.py
| | | |-- dbapi.py
| | | |-- errors.py
| | | |-- interface.py
| | | |-- protocol.py
| | | |-- types.py
| | | `-- util.py
| | |-- porter.py
| | |-- porter2.py
| | |-- pptable.py
| | |-- pymysql
| | | |-- __init__.py
| | | |-- charset.py
| | | |-- connections.py
| | | |-- constants
| | | | |-- CLIENT.py
| | | | |-- COMMAND.py
| | | | |-- ER.py
| | | | |-- FIELD_TYPE.py
| | | | |-- FLAG.py
| | | | |-- SERVER_STATUS.py
| | | | `-- __init__.py
| | | |-- converters.py
| | | |-- cursors.py
| | | |-- err.py
| | | |-- times.py
| | | `-- util.py
| | |-- pyparsing.py
| | |-- pyperclip.py
| | |-- pyreadline
| | | |-- __init__.py
| | | |-- clipboard
| | | | |-- __init__.py
| | | | `-- win32_clipboard.py
| | | |-- configuration
| | | | |-- pyreadlineconfig.ini
| | | | `-- startup.py
| | | |-- console
| | | | |-- __init__.py
| | | | |-- ansi.py
| | | | |-- console.py
| | | | |-- console_attributes.py
| | | | |-- consolebase.py
| | | | |-- event.py
| | | | `-- ironpython_console.py
| | | |-- error.py
| | | |-- get_doc.py
| | | |-- keysyms
| | | | |-- __init__.py
| | | | |-- common.py
| | | | |-- keysyms.py
| | | | `-- winconstants.py
| | | |-- lineeditor
| | | | |-- __init__.py
| | | | |-- history.py
| | | | |-- lineobj.py
| | | | `-- wordmatcher.py
| | | |-- logger.py
| | | |-- logserver.py
| | | |-- modes
| | | | |-- __init__.py
| | | | |-- basemode.py
| | | | |-- emacs.py
| | | | |-- notemacs.py
| | | | `-- vi.py
| | | |-- release.py
| | | |-- rlmain.py
| | | `-- unicode_helper.py
| | |-- readme.txt
| | |-- reimport.py
| | |-- schemaUtils.py
| | |-- setpath.py
| | |-- simpleutils.py
| | |-- sqlitetypes.py
| | |-- sqlparse
| | | |-- __init__.py
| | | |-- engine
| | | | |-- __init__.py
| | | | |-- filter.py
| | | | `-- grouping.py
| | | |-- filters.py
| | | |-- formatter.py
| | | |-- keywords.py
| | | |-- lexer.py
| | | |-- sql.py
| | | `-- tokens.py
| | |-- stopwordlist.py
| | |-- stringdists.py
| | |-- textcat.py
| | |-- unicodeops.py
| | |-- vtoutgtable.py
| | |-- winunicode.py
| | `-- ziputils.py
| `-- monetdb.py
|-- YeSQLite
| |-- LICENSE.txt
| |-- demo
| | |-- continents.tsv
| | `-- countries.tsv
| |-- docs
| | |-- builddocs.sh
| | |-- generate_function_doc.py
| | |-- html
| | | `-- readme.txt
| | `-- source
| | |-- _static
| | | |-- jsMath
| | | | |-- blank.gif
| | | | |-- easy
| | | | | `-- load.js
| | | | |-- extensions
| | | | | |-- AMSmath.js
| | | | | |-- AMSsymbols.js
| | | | | |-- HTML.js
| | | | | |-- autobold.js
| | | | | |-- bbox.js
| | | | | |-- boldsymbol.js
| | | | | |-- double-click.js
| | | | | |-- eqn-number.js
| | | | | |-- fbox.js
| | | | | |-- font.js
| | | | | |-- leaders.js
| | | | | |-- mathchoice.js
| | | | | |-- mimeTeX.js
| | | | | |-- moreArrows.js
| | | | | |-- newcommand.js
| | | | | |-- underset-overset.js
| | | | | `-- verb.js
| | | | |-- jsMath-BaKoMa-fonts.js
| | | | |-- jsMath-autoload.html
| | | | |-- jsMath-controls.html
| | | | |-- jsMath-easy-load.js
| | | | |-- jsMath-fallback-mac-mozilla.js
| | | | |-- jsMath-fallback-mac-msie.js
| | | | |-- jsMath-fallback-mac.js
| | | | |-- jsMath-fallback-pc.js
| | | | |-- jsMath-fallback-symbols.js
| | | | |-- jsMath-fallback-unix.js
| | | | |-- jsMath-global-controls.html
| | | | |-- jsMath-global.html
| | | | |-- jsMath-loader-omniweb4.js
| | | | |-- jsMath-loader-post.html
| | | | |-- jsMath-loader.html
| | | | |-- jsMath-msie-mac.js
| | | | |-- jsMath-old-browsers.js
| | | | |-- jsMath.js
| | | | |-- local
| | | | | `-- macros.js
| | | | |-- plugins
| | | | | |-- CHMmode.js
| | | | | |-- autoload.js
| | | | | |-- global.js
| | | | | |-- mimeTeX.js
| | | | | |-- noCache.js
| | | | | |-- noGlobal.js
| | | | | |-- noImageFonts.js
| | | | | |-- smallFonts.js
| | | | | |-- spriteImageFonts.js
| | | | | `-- tex2math.js
| | | | |-- test
| | | | | |-- index-images.html
| | | | | |-- index.html
| | | | | |-- jsMath40.jpg
| | | | | `-- sample.html
| | | | `-- uncompressed
| | | | |-- def.js
| | | | |-- font.js
| | | | |-- jsMath-fallback-mac.js
| | | | |-- jsMath-fallback-pc.js
| | | | |-- jsMath-fallback-symbols.js
| | | | |-- jsMath-fallback-unix.js
| | | | `-- jsMath.js
| | | `-- madis-screen.png
| | |-- about.txt
| | |-- conf.py
| | |-- examples.txt
| | |-- extending.txt
| | |-- index.txt
| | |-- install.txt
| | |-- license.txt
| | |-- madislog.png
| | |-- manual.txt
| | |-- modules.txt
| | |-- people.txt
| | |-- quickstart.txt
| | |-- thanks.txt
| | |-- usefulnotes.txt
| | |-- vtablehowto.txt
| | `-- workflows.txt
| |-- examples
| | |-- citeseer
| | | `-- cite.sql
| | |-- dblp
| | | `-- dblp.sql
| | |-- diavgeia
| | | |-- diavgeia.sql
| | | `-- diavgeiaget.py
| | `-- readme.txt
| |-- functions
| | |-- __init__.py
| | |-- aggregate
| | | |-- __init__.py
| | | |-- date.py
| | | |-- graph.py
| | | |-- jpacks.py
| | | |-- mining.py
| | | |-- partialsort.py
| | | |-- selection.py
| | | |-- setpath.py
| | | |-- skcluster.py
| | | |-- skdimred.py
| | | |-- statistics.py
| | | |-- subgroup.py
| | | |-- text.py
| | | `-- util.py
| | |-- conf.py
| | |-- row
| | | |-- __init__.py
| | | |-- boolean.py
| | | |-- date.py
| | | |-- evals.py
| | | |-- fileops.py
| | | |-- formating.py
| | | |-- htmlops.py
| | | |-- iptools.py
| | | |-- jpacks.py
| | | |-- langtools.py
| | | |-- logparse.py
| | | |-- mathops.py
| | | |-- setpath.py
| | | |-- settings.py
| | | |-- similarity.py
| | | |-- stopwords.py
| | | |-- stringdist.py
| | | |-- termsetops.py
| | | |-- testing
| | | | `-- sales.tsv
| | | |-- text.py
| | | |-- tzconverter.py
| | | |-- util.py
| | | `-- variables.py
| | |-- setpath.py
| | |-- sqltransform.py
| | `-- vtable
| | |-- __init__.py
| | |-- cache.py
| | |-- clipboard.py
| | |-- clipout.py
| | |-- coltypes.py
| | |-- continue.py
| | |-- dirfiles.py
| | |-- examplevt.py
| | |-- exec.py
| | |-- expand.py
| | |-- file.py
| | |-- flow.py
| | |-- fromeav.py
| | |-- hidden.py
| | |-- jsonpipe.py
| | |-- mysql.py
| | |-- oaiget.py
| | |-- oracle.py
| | |-- ordered.py
| | |-- output.py
| | |-- pipe.py
| | |-- postgres.py
| | |-- queryplan.py
| | |-- range.py
| | |-- rowidvt.py
| | |-- sample.py
| | |-- setpath.py
| | |-- setschema.py
| | |-- skpredict.py
| | |-- sktrain.py
| | |-- slidingwindow.py
| | |-- sqlite.py
| | |-- stdinput.py
| | |-- testing
| | | |-- GeoIPCountryCSV.zip
| | | |-- colpref.csv
| | | |-- colpref.tsv
| | | |-- colpref.tsv.gz
| | | |-- colpref.zip
| | | |-- internalflow.sql
| | | |-- testflow.sql
| | | |-- testtable.sql
| | | `-- topflow.sql
| | |-- timeslidingwindow.py
| | |-- toeav.py
| | |-- unindexed.py
| | |-- unionalldb.py
| | |-- variables.py
| | |-- vtbase.py
| | |-- vtiterable.py
| | |-- vtout.py
| | |-- webtable.py
| | |-- whilevt.py
| | `-- xmlparse.py
| |-- functionslocal
| | |-- __init__.py
| | |-- aggregate
| | | `-- __init__.py
| | |-- row
| | | `-- __init__.py
| | `-- vtable
| | `-- __init__.py
| |-- lib
| | |-- LM
| | | |-- DisabledLMs
| | | | |-- afrikaans.lm
| | | | |-- amharic-utf.lm
| | | | |-- arabic-iso8859_6.lm
| | | | |-- arabic-windows1256.lm
| | | | |-- basque.lm
| | | | |-- breton.lm
| | | | |-- catalan.lm
| | | | |-- chinese-big5.lm
| | | | |-- chinese-gb2312.lm
| | | | |-- drents.lm
| | | | |-- esperanto.lm
| | | | |-- frisian.lm
| | | | |-- greek-iso8859-7.lm
| | | | |-- greek-windows1253.lm
| | | | |-- hebrew-iso8859_8.lm
| | | | |-- hindi.lm
| | | | |-- indonesian.lm
| | | | |-- irish.lm
| | | | |-- japanese-euc_jp.lm
| | | | |-- japanese-shift_jis.lm
| | | | |-- korean.lm
| | | | |-- malay.lm
| | | | |-- manx.lm
| | | | |-- marathi.lm
| | | | |-- middle_frisian.lm
| | | | |-- mingo.lm
| | | | |-- nepali.lm
| | | | |-- persian.lm
| | | | |-- quechua.lm
| | | | |-- rumantsch.lm
| | | | |-- sanskrit.lm
| | | | |-- scots.lm
| | | | |-- scots_gaelic.lm
| | | | |-- swahili.lm
| | | | |-- tagalog.lm
| | | | |-- tamil.lm
| | | | |-- thai.lm
| | | | |-- ukrainian-koi8_r.lm
| | | | |-- vietnamese.lm
| | | | |-- welsh.lm
| | | | `-- yiddish-utf.lm
| | | |-- albanian.lm
| | | |-- armenian.lm
| | | |-- belarus-windows1251.lm
| | | |-- bosnian.lm
| | | |-- bulgarian-iso8859_5.lm
| | | |-- croatian-ascii.lm
| | | |-- czech-iso8859_2.lm
| | | |-- danish.lm
| | | |-- dutch.lm
| | | |-- english.lm
| | | |-- estonian.lm
| | | |-- finnish.lm
| | | |-- french.lm
| | | |-- georgian.lm
| | | |-- german.lm
| | | |-- greek-utf.lm
| | | |-- hungarian.lm
| | | |-- icelandic.lm
| | | |-- italian.lm
| | | |-- latin.lm
| | | |-- latvian.lm
| | | |-- lithuanian.lm
| | | |-- norwegian.lm
| | | |-- polish.lm
| | | |-- portuguese.lm
| | | |-- romanian.lm
| | | |-- russian-iso8859_5.lm
| | | |-- russian-koi8_r.lm
| | | |-- russian-windows1251.lm
| | | |-- serbian-ascii.lm
| | | |-- slovak-ascii.lm
| | | |-- slovak-windows1250.lm
| | | |-- slovenian-ascii.lm
| | | |-- slovenian-iso8859_2.lm
| | | |-- spanish.lm
| | | |-- swedish.lm
| | | `-- turkish.lm
| | |-- TableHTMLParser.py
| | |-- __init__.py
| | |-- argsparse.py
| | |-- boolops.py
| | |-- chardet
| | | |-- __init__.py
| | | |-- big5freq.py
| | | |-- big5prober.py
| | | |-- chardistribution.py
| | | |-- charsetgroupprober.py
| | | |-- charsetprober.py
| | | |-- codingstatemachine.py
| | | |-- constants.py
| | | |-- docs
| | | | |-- css
| | | | | `-- chardet.css
| | | | |-- faq.html
| | | | |-- history.html
| | | | |-- how-it-works.html
| | | | |-- images
| | | | | |-- caution.png
| | | | | |-- important.png
| | | | | |-- note.png
| | | | | |-- permalink.gif
| | | | | |-- tip.png
| | | | | `-- warning.png
| | | | |-- index.html
| | | | |-- license.html
| | | | |-- supported-encodings.html
| | | | `-- usage.html
| | | |-- escprober.py
| | | |-- escsm.py
| | | |-- eucjpprober.py
| | | |-- euckrfreq.py
| | | |-- euckrprober.py
| | | |-- euctwfreq.py
| | | |-- euctwprober.py
| | | |-- gb2312freq.py
| | | |-- gb2312prober.py
| | | |-- hebrewprober.py
| | | |-- jisfreq.py
| | | |-- jpcntx.py
| | | |-- langbulgarianmodel.py
| | | |-- langcyrillicmodel.py
| | | |-- langgreekmodel.py
| | | |-- langhebrewmodel.py
| | | |-- langhungarianmodel.py
| | | |-- langthaimodel.py
| | | |-- latin1prober.py
| | | |-- mbcharsetprober.py
| | | |-- mbcsgroupprober.py
| | | |-- mbcssm.py
| | | |-- sbcharsetprober.py
| | | |-- sbcsgroupprober.py
| | | |-- sjisprober.py
| | | |-- test.py
| | | |-- universaldetector.py
| | | `-- utf8prober.py
| | |-- collections26.py
| | |-- colorama
| | | |-- LICENSE.txt
| | | |-- __init__.py
| | | |-- ansi.py
| | | |-- ansitowin32.py
| | | |-- initialise.py
| | | |-- win32.py
| | | `-- winterm.py
| | |-- conutils.py
| | |-- dateutil
| | | |-- LICENSE
| | | |-- __init__.py
| | | |-- easter.py
| | | |-- parser.py
| | | |-- relativedelta.py
| | | |-- rrule.py
| | | |-- tz.py
| | | |-- tzwin.py
| | | `-- zoneinfo
| | | |-- __init__.py
| | | `-- zoneinfo-2010g.tar.gz
| | |-- dsv.py
| | |-- fastavro
| | | |-- NOTICE.txt
| | | |-- PKG-INFO
| | | |-- __init__.py
| | | |-- __main__.py
| | | |-- reader.py
| | | |-- six.py
| | | `-- writer.py
| | |-- gtable.py
| | |-- gzip32.py
| | |-- gzip34.py
| | |-- htmlentities.py
| | |-- inoutparsing.py
| | |-- ipaddr.py
| | |-- iso8601.py
| | |-- iterutils.py
| | |-- jaydebeapi
| | | |-- COPYING.LESSER
| | | |-- __init__.py
| | | `-- dbapi2.py
| | |-- jdbc
| | | `-- readme.txt
| | |-- jopts.py
| | |-- jsonpath.py
| | |-- kdtree.py
| | |-- listser.py
| | |-- madcomp.py
| | |-- memoize.py
| | |-- pg8000
| | | |-- __init__.py
| | | |-- dbapi.py
| | | |-- errors.py
| | | |-- interface.py
| | | |-- protocol.py
| | | |-- types.py
| | | `-- util.py
| | |-- porter.py
| | |-- porter2.py
| | |-- pptable.py
| | |-- pymysql
| | | |-- __init__.py
| | | |-- charset.py
| | | |-- connections.py
| | | |-- constants
| | | | |-- CLIENT.py
| | | | |-- COMMAND.py
| | | | |-- ER.py
| | | | |-- FIELD_TYPE.py
| | | | |-- FLAG.py
| | | | |-- SERVER_STATUS.py
| | | | `-- __init__.py
| | | |-- converters.py
| | | |-- cursors.py
| | | |-- err.py
| | | |-- times.py
| | | `-- util.py
| | |-- pyparsing.py
| | |-- pyperclip.py
| | |-- pyreadline
| | | |-- __init__.py
| | | |-- clipboard
| | | | |-- __init__.py
| | | | `-- win32_clipboard.py
| | | |-- configuration
| | | | |-- pyreadlineconfig.ini
| | | | `-- startup.py
| | | |-- console
| | | | |-- __init__.py
| | | | |-- ansi.py
| | | | |-- console.py
| | | | |-- console_attributes.py
| | | | |-- consolebase.py
| | | | |-- event.py
| | | | `-- ironpython_console.py
| | | |-- error.py
| | | |-- get_doc.py
| | | |-- keysyms
| | | | |-- __init__.py
| | | | |-- common.py
| | | | |-- keysyms.py
| | | | `-- winconstants.py
| | | |-- lineeditor
| | | | |-- __init__.py
| | | | |-- history.py
| | | | |-- lineobj.py
| | | | `-- wordmatcher.py
| | | |-- logger.py
| | | |-- logserver.py
| | | |-- modes
| | | | |-- __init__.py
| | | | |-- basemode.py
| | | | |-- emacs.py
| | | | |-- notemacs.py
| | | | `-- vi.py
| | | |-- release.py
| | | |-- rlmain.py
| | | `-- unicode_helper.py
| | |-- readme.txt
| | |-- reimport.py
| | |-- schemaUtils.py
| | |-- setpath.py
| | |-- simpleutils.py
| | |-- sqlitetypes.py
| | |-- sqlparse
| | | |-- __init__.py
| | | |-- engine
| | | | |-- __init__.py
| | | | |-- filter.py
| | | | `-- grouping.py
| | | |-- filters.py
| | | |-- formatter.py
| | | |-- keywords.py
| | | |-- lexer.py
| | | |-- sql.py
| | | `-- tokens.py
| | |-- stopwordlist.py
| | |-- stringdists.py
| | |-- textcat.py
| | |-- unicodeops.py
| | |-- vtoutgtable.py
| | |-- winunicode.py
| | `-- ziputils.py
| |-- libexternal
| | `-- __init__.py
| |-- mexec.py
| |-- mterm.py
| |-- pypylib
| | |-- apsw.py
| | |-- apsw.py.bak
| | |-- msgpack
| | | |-- COPYING
| | | |-- __init__.py
| | | |-- _version.py
| | | |-- exceptions.py
| | | `-- fallback.py
| | `-- readme.txt
| |-- tests
| | `-- readme.txt
| `-- yesql.py
|-- data
| |-- GlobalAirportDatabase.txt
| |-- L_CARRIER_HISTORY.csv
| |-- flights.csv
| |-- loaddata_sqlite.sql
| |-- loadflights.sql
| |-- loadschema.sql
| `-- zillow.csv
|-- exec.sh
|-- sql_queries
| |-- flights.sql
| |-- flights_sqlite.sql
| |-- zillow.sql
| `-- zillow_sqlite.sql
`-- udfs
|-- __init__.py
|-- flights.py
`-- zillow.py
对于YeSQL-SQLite的实现,使用了CFFI修改apsw库,再通过apsw库实现udf及后续的操作
个人评价
Really interesting!😀很多我在Demo想问的问题在这里都找到了答案
每个实验结果都能在理论当中找到对应的部分
不过Python3.13还是3.14计划引入JIT并去除GIL锁,不知道那时候YeSQL是否还能跑的更快
这个组在ICDE 2023和VLDB 2023有后续进展,值得后续跟进