2
0

quick_bench.sh 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #!/bin/bash
  2. set -e
  3. echo "========================================"
  4. echo "PizzaSQL Quick Benchmarks"
  5. echo "========================================"
  6. echo ""
  7. # Configuration
  8. PIZZASQL_HTTP_URL="http://localhost:8080"
  9. PIZZASQL_PG_HOST="localhost"
  10. PIZZASQL_PG_PORT="5433"
  11. POSTGRES_HOST="localhost"
  12. POSTGRES_PORT="5432"
  13. POSTGRES_DB="postgres"
  14. POSTGRES_USER="$USER"
  15. SQLITE_DB="/tmp/pizzasql_benchmark.db"
  16. NUM_ROWS=1000
  17. NUM_QUERIES=100
  18. # Colors
  19. GREEN='\033[0;32m'
  20. BLUE='\033[0;34m'
  21. YELLOW='\033[1;33m'
  22. NC='\033[0m' # No Color
  23. echo -e "${BLUE}Configuration:${NC}"
  24. echo " Rows to insert: $NUM_ROWS"
  25. echo " Query iterations: $NUM_QUERIES"
  26. echo " PizzaSQL HTTP: $PIZZASQL_HTTP_URL"
  27. echo " PizzaSQL PostgreSQL: $PIZZASQL_PG_HOST:$PIZZASQL_PG_PORT"
  28. echo " PostgreSQL: $POSTGRES_HOST:$POSTGRES_PORT"
  29. echo " SQLite DB: $SQLITE_DB"
  30. echo ""
  31. # Cleanup
  32. rm -f $SQLITE_DB
  33. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  34. -H "Content-Type: application/json" \
  35. -d '{"sql":"DROP TABLE IF EXISTS users"}' > /dev/null 2>&1 || true
  36. PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -c "DROP TABLE IF EXISTS users_pg" > /dev/null 2>&1 || true
  37. PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -c "DROP TABLE IF EXISTS users_bench" > /dev/null 2>&1 || true
  38. echo -e "${GREEN}=== Setup: Creating Tables ===${NC}"
  39. echo ""
  40. # SQLite
  41. sqlite3 $SQLITE_DB "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, age INTEGER, active INTEGER)"
  42. echo "✓ SQLite table created"
  43. # PizzaSQL HTTP
  44. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  45. -H "Content-Type: application/json" \
  46. -d '{"sql":"DROP TABLE IF EXISTS users"}' > /dev/null 2>&1 || true
  47. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  48. -H "Content-Type: application/json" \
  49. -d '{"sql":"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, age INTEGER, active INTEGER)"}' > /dev/null
  50. echo "✓ PizzaSQL HTTP table created"
  51. # PizzaSQL PostgreSQL
  52. PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -c "DROP TABLE IF EXISTS users_pg" > /dev/null 2>&1 || true
  53. PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -c "CREATE TABLE users_pg (id INTEGER PRIMARY KEY, name TEXT, email TEXT, age INTEGER, active INTEGER)" > /dev/null 2>&1
  54. echo "✓ PizzaSQL PostgreSQL table created"
  55. # PostgreSQL
  56. PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -c "DROP TABLE IF EXISTS users_bench" > /dev/null 2>&1 || true
  57. PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -c "CREATE TABLE users_bench (id SERIAL PRIMARY KEY, name TEXT, email TEXT, age INTEGER, active INTEGER)" > /dev/null 2>&1
  58. echo "✓ PostgreSQL table created"
  59. echo ""
  60. echo -e "${GREEN}=== Benchmark 1: INSERT $NUM_ROWS Rows ===${NC}"
  61. echo ""
  62. # SQLite
  63. start=$(date +%s%N)
  64. for i in $(seq 1 $NUM_ROWS); do
  65. sqlite3 $SQLITE_DB "INSERT INTO users (name, email, age, active) VALUES ('User$i', 'user$i@test.com', $((20 + $i % 50)), 1)" 2>/dev/null
  66. done
  67. end=$(date +%s%N)
  68. sqlite_insert_ms=$(( (end - start) / 1000000 ))
  69. sqlite_insert_ops=$(echo "scale=0; $NUM_ROWS * 1000 / $sqlite_insert_ms" | bc)
  70. echo " SQLite: ${sqlite_insert_ms}ms total (${sqlite_insert_ops} inserts/sec)"
  71. # PizzaSQL HTTP
  72. start=$(date +%s%N)
  73. for i in $(seq 1 $NUM_ROWS); do
  74. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  75. -H "Content-Type: application/json" \
  76. -d "{\"sql\":\"INSERT INTO users (name, email, age, active) VALUES ('User$i', 'user$i@test.com', $((20 + $i % 50)), 1)\"}" > /dev/null
  77. done
  78. end=$(date +%s%N)
  79. http_insert_ms=$(( (end - start) / 1000000 ))
  80. http_insert_ops=$(echo "scale=0; $NUM_ROWS * 1000 / $http_insert_ms" | bc)
  81. echo " PizzaSQL (HTTP): ${http_insert_ms}ms total (${http_insert_ops} inserts/sec)"
  82. # PizzaSQL PostgreSQL (using single connection with transaction)
  83. start=$(date +%s%N)
  84. {
  85. echo "BEGIN;"
  86. for i in $(seq 1 $NUM_ROWS); do
  87. echo "INSERT INTO users_pg (name, email, age, active) VALUES ('User$i', 'user$i@test.com', $((20 + $i % 50)), 1);"
  88. done
  89. echo "COMMIT;"
  90. } | PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -q > /dev/null 2>&1
  91. end=$(date +%s%N)
  92. pg_insert_ms=$(( (end - start) / 1000000 ))
  93. pg_insert_ops=$(echo "scale=0; $NUM_ROWS * 1000 / $pg_insert_ms" | bc)
  94. echo " PizzaSQL (Postgres): ${pg_insert_ms}ms total (${pg_insert_ops} inserts/sec)"
  95. # PostgreSQL
  96. start=$(date +%s%N)
  97. {
  98. echo "BEGIN;"
  99. for i in $(seq 1 $NUM_ROWS); do
  100. echo "INSERT INTO users_bench (name, email, age, active) VALUES ('User$i', 'user$i@test.com', $((20 + $i % 50)), 1);"
  101. done
  102. echo "COMMIT;"
  103. } | PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -q > /dev/null 2>&1
  104. end=$(date +%s%N)
  105. postgres_insert_ms=$(( (end - start) / 1000000 ))
  106. postgres_insert_ops=$(echo "scale=0; $NUM_ROWS * 1000 / $postgres_insert_ms" | bc)
  107. echo " PostgreSQL: ${postgres_insert_ms}ms total (${postgres_insert_ops} inserts/sec)"
  108. echo ""
  109. echo -e "${GREEN}=== Benchmark 2: SELECT (Full Scan) ===${NC}"
  110. echo ""
  111. # SQLite
  112. start=$(date +%s%N)
  113. for i in $(seq 1 $NUM_QUERIES); do
  114. sqlite3 $SQLITE_DB "SELECT * FROM users WHERE age > 30" > /dev/null
  115. done
  116. end=$(date +%s%N)
  117. sqlite_select_ms=$(( (end - start) / 1000000 ))
  118. sqlite_select_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $sqlite_select_ms" | bc)
  119. echo " SQLite: ${sqlite_select_ms}ms total (${sqlite_select_ops} queries/sec)"
  120. # PizzaSQL HTTP
  121. start=$(date +%s%N)
  122. for i in $(seq 1 $NUM_QUERIES); do
  123. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  124. -H "Content-Type: application/json" \
  125. -d '{"sql":"SELECT * FROM users WHERE age > 30"}' > /dev/null
  126. done
  127. end=$(date +%s%N)
  128. http_select_ms=$(( (end - start) / 1000000 ))
  129. http_select_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $http_select_ms" | bc)
  130. echo " PizzaSQL (HTTP): ${http_select_ms}ms total (${http_select_ops} queries/sec)"
  131. # PizzaSQL PostgreSQL (using single connection)
  132. start=$(date +%s%N)
  133. {
  134. for i in $(seq 1 $NUM_QUERIES); do
  135. echo "SELECT * FROM users_pg WHERE age > 30;"
  136. done
  137. } | PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -q > /dev/null 2>&1
  138. end=$(date +%s%N)
  139. pg_select_ms=$(( (end - start) / 1000000 ))
  140. pg_select_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $pg_select_ms" | bc)
  141. echo " PizzaSQL (Postgres): ${pg_select_ms}ms total (${pg_select_ops} queries/sec)"
  142. # PostgreSQL
  143. start=$(date +%s%N)
  144. {
  145. for i in $(seq 1 $NUM_QUERIES); do
  146. echo "SELECT * FROM users_bench WHERE age > 30;"
  147. done
  148. } | PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -q > /dev/null 2>&1
  149. end=$(date +%s%N)
  150. postgres_select_ms=$(( (end - start) / 1000000 ))
  151. postgres_select_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $postgres_select_ms" | bc)
  152. echo " PostgreSQL: ${postgres_select_ms}ms total (${postgres_select_ops} queries/sec)"
  153. echo ""
  154. echo -e "${GREEN}=== Benchmark 3: CREATE INDEX ===${NC}"
  155. echo ""
  156. # SQLite
  157. start=$(date +%s%N)
  158. sqlite3 $SQLITE_DB "CREATE INDEX idx_age ON users(age)" > /dev/null
  159. end=$(date +%s%N)
  160. sqlite_index_ms=$(( (end - start) / 1000000 ))
  161. echo " SQLite: ${sqlite_index_ms}ms"
  162. # PizzaSQL HTTP
  163. start=$(date +%s%N)
  164. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  165. -H "Content-Type: application/json" \
  166. -d '{"sql":"CREATE INDEX idx_age ON users(age)"}' > /dev/null
  167. end=$(date +%s%N)
  168. http_index_ms=$(( (end - start) / 1000000 ))
  169. echo " PizzaSQL (HTTP): ${http_index_ms}ms"
  170. # PizzaSQL PostgreSQL
  171. start=$(date +%s%N)
  172. PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -c "CREATE INDEX idx_age_pg ON users_pg(age)" > /dev/null 2>&1
  173. end=$(date +%s%N)
  174. pg_index_ms=$(( (end - start) / 1000000 ))
  175. echo " PizzaSQL (Postgres): ${pg_index_ms}ms"
  176. # PostgreSQL
  177. start=$(date +%s%N)
  178. PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -c "CREATE INDEX idx_age_bench ON users_bench(age)" > /dev/null 2>&1
  179. end=$(date +%s%N)
  180. postgres_index_ms=$(( (end - start) / 1000000 ))
  181. echo " PostgreSQL: ${postgres_index_ms}ms"
  182. echo ""
  183. echo -e "${GREEN}=== Benchmark 4: SELECT with INDEX ===${NC}"
  184. echo ""
  185. # SQLite
  186. start=$(date +%s%N)
  187. for i in $(seq 1 $NUM_QUERIES); do
  188. sqlite3 $SQLITE_DB "SELECT * FROM users WHERE age = 35" > /dev/null
  189. done
  190. end=$(date +%s%N)
  191. sqlite_indexed_ms=$(( (end - start) / 1000000 ))
  192. sqlite_indexed_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $sqlite_indexed_ms" | bc)
  193. echo " SQLite: ${sqlite_indexed_ms}ms total (${sqlite_indexed_ops} queries/sec)"
  194. # PizzaSQL HTTP
  195. start=$(date +%s%N)
  196. for i in $(seq 1 $NUM_QUERIES); do
  197. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  198. -H "Content-Type: application/json" \
  199. -d '{"sql":"SELECT * FROM users WHERE age = 35"}' > /dev/null
  200. done
  201. end=$(date +%s%N)
  202. http_indexed_ms=$(( (end - start) / 1000000 ))
  203. http_indexed_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $http_indexed_ms" | bc)
  204. echo " PizzaSQL (HTTP): ${http_indexed_ms}ms total (${http_indexed_ops} queries/sec)"
  205. # PizzaSQL PostgreSQL (using single connection)
  206. start=$(date +%s%N)
  207. {
  208. for i in $(seq 1 $NUM_QUERIES); do
  209. echo "SELECT * FROM users_pg WHERE age = 35;"
  210. done
  211. } | PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -q > /dev/null 2>&1
  212. end=$(date +%s%N)
  213. pg_indexed_ms=$(( (end - start) / 1000000 ))
  214. pg_indexed_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $pg_indexed_ms" | bc)
  215. echo " PizzaSQL (Postgres): ${pg_indexed_ms}ms total (${pg_indexed_ops} queries/sec)"
  216. # PostgreSQL
  217. start=$(date +%s%N)
  218. {
  219. for i in $(seq 1 $NUM_QUERIES); do
  220. echo "SELECT * FROM users_bench WHERE age = 35;"
  221. done
  222. } | PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -q > /dev/null 2>&1
  223. end=$(date +%s%N)
  224. postgres_indexed_ms=$(( (end - start) / 1000000 ))
  225. postgres_indexed_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $postgres_indexed_ms" | bc)
  226. echo " PostgreSQL: ${postgres_indexed_ms}ms total (${postgres_indexed_ops} queries/sec)"
  227. echo ""
  228. echo -e "${GREEN}=== Benchmark 5: Aggregate Query ===${NC}"
  229. echo ""
  230. # SQLite
  231. start=$(date +%s%N)
  232. for i in $(seq 1 $NUM_QUERIES); do
  233. sqlite3 $SQLITE_DB "SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM users GROUP BY age" > /dev/null
  234. done
  235. end=$(date +%s%N)
  236. sqlite_agg_ms=$(( (end - start) / 1000000 ))
  237. sqlite_agg_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $sqlite_agg_ms" | bc)
  238. echo " SQLite: ${sqlite_agg_ms}ms total (${sqlite_agg_ops} queries/sec)"
  239. # PizzaSQL HTTP
  240. start=$(date +%s%N)
  241. for i in $(seq 1 $NUM_QUERIES); do
  242. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  243. -H "Content-Type: application/json" \
  244. -d '{"sql":"SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM users GROUP BY age"}' > /dev/null
  245. done
  246. end=$(date +%s%N)
  247. http_agg_ms=$(( (end - start) / 1000000 ))
  248. http_agg_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $http_agg_ms" | bc)
  249. echo " PizzaSQL (HTTP): ${http_agg_ms}ms total (${http_agg_ops} queries/sec)"
  250. # PizzaSQL PostgreSQL (using single connection)
  251. start=$(date +%s%N)
  252. {
  253. for i in $(seq 1 $NUM_QUERIES); do
  254. echo "SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM users_pg GROUP BY age;"
  255. done
  256. } | PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -q > /dev/null 2>&1
  257. end=$(date +%s%N)
  258. pg_agg_ms=$(( (end - start) / 1000000 ))
  259. pg_agg_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $pg_agg_ms" | bc)
  260. echo " PizzaSQL (Postgres): ${pg_agg_ms}ms total (${pg_agg_ops} queries/sec)"
  261. # PostgreSQL
  262. start=$(date +%s%N)
  263. {
  264. for i in $(seq 1 $NUM_QUERIES); do
  265. echo "SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM users_bench GROUP BY age;"
  266. done
  267. } | PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -q > /dev/null 2>&1
  268. end=$(date +%s%N)
  269. postgres_agg_ms=$(( (end - start) / 1000000 ))
  270. postgres_agg_ops=$(echo "scale=0; $NUM_QUERIES * 1000 / $postgres_agg_ms" | bc)
  271. echo " PostgreSQL: ${postgres_agg_ms}ms total (${postgres_agg_ops} queries/sec)"
  272. echo ""
  273. echo -e "${BLUE}========================================${NC}"
  274. echo -e "${BLUE}Summary${NC}"
  275. echo -e "${BLUE}========================================${NC}"
  276. echo ""
  277. printf "%-25s %-20s %-20s %-20s %-20s\n" "Operation" "SQLite" "PizzaSQL (HTTP)" "PizzaSQL (PG Wire)" "PostgreSQL"
  278. printf "%-25s %-20s %-20s %-20s %-20s\n" "-------------------------" "--------------------" "--------------------" "--------------------" "--------------------"
  279. printf "%-25s %-20s %-20s %-20s %-20s\n" "INSERT ($NUM_ROWS rows)" "${sqlite_insert_ops} ops/s" "${http_insert_ops} ops/s" "${pg_insert_ops} ops/s" "${postgres_insert_ops} ops/s"
  280. printf "%-25s %-20s %-20s %-20s %-20s\n" "SELECT (no index)" "${sqlite_select_ops} q/s" "${http_select_ops} q/s" "${pg_select_ops} q/s" "${postgres_select_ops} q/s"
  281. printf "%-25s %-20s %-20s %-20s %-20s\n" "CREATE INDEX" "${sqlite_index_ms} ms" "${http_index_ms} ms" "${pg_index_ms} ms" "${postgres_index_ms} ms"
  282. printf "%-25s %-20s %-20s %-20s %-20s\n" "SELECT (indexed)" "${sqlite_indexed_ops} q/s" "${http_indexed_ops} q/s" "${pg_indexed_ops} q/s" "${postgres_indexed_ops} q/s"
  283. printf "%-25s %-20s %-20s %-20s %-20s\n" "AGGREGATE" "${sqlite_agg_ops} q/s" "${http_agg_ops} q/s" "${pg_agg_ops} q/s" "${postgres_agg_ops} q/s"
  284. echo ""
  285. echo -e "${GREEN}Benchmarks completed!${NC}"
  286. # Cleanup
  287. echo ""
  288. echo -e "${YELLOW}Cleaning up...${NC}"
  289. rm -f $SQLITE_DB
  290. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  291. -H "Content-Type: application/json" \
  292. -d '{"sql":"DROP TABLE IF EXISTS users"}' > /dev/null 2>&1 || true
  293. PGPASSWORD="" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -U postgres -d pizzasql -c "DROP TABLE IF EXISTS users_pg" > /dev/null 2>&1 || true
  294. PGPASSWORD="" psql -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER -d $POSTGRES_DB -c "DROP TABLE IF EXISTS users_bench" > /dev/null 2>&1 || true
  295. echo "✓ Cleanup complete"