run_benchmarks.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #!/bin/bash
  2. set -e
  3. echo "========================================"
  4. echo "PizzaSQL Benchmarks"
  5. echo "========================================"
  6. echo ""
  7. # Configuration
  8. PIZZASQL_HTTP_URL="http://localhost:8080"
  9. PIZZASQL_PG_HOST="localhost"
  10. PIZZASQL_PG_PORT="5432"
  11. SQLITE_DB="benchmark.db"
  12. NUM_ROWS=10000
  13. NUM_ITERATIONS=1000
  14. # Colors
  15. GREEN='\033[0;32m'
  16. BLUE='\033[0;34m'
  17. YELLOW='\033[1;33m'
  18. NC='\033[0m' # No Color
  19. # Check dependencies
  20. command -v sqlite3 >/dev/null 2>&1 || { echo "sqlite3 is required but not installed. Aborting." >&2; exit 1; }
  21. command -v psql >/dev/null 2>&1 || { echo "psql is required but not installed. Aborting." >&2; exit 1; }
  22. command -v curl >/dev/null 2>&1 || { echo "curl is required but not installed. Aborting." >&2; exit 1; }
  23. echo -e "${BLUE}Configuration:${NC}"
  24. echo " Rows to insert: $NUM_ROWS"
  25. echo " Query iterations: $NUM_ITERATIONS"
  26. echo " PizzaSQL HTTP: $PIZZASQL_HTTP_URL"
  27. echo " PizzaSQL PostgreSQL: $PIZZASQL_PG_HOST:$PIZZASQL_PG_PORT"
  28. echo " SQLite DB: $SQLITE_DB"
  29. echo ""
  30. # Function to time a command
  31. time_command() {
  32. local name=$1
  33. shift
  34. local start=$(date +%s%N)
  35. "$@" > /dev/null 2>&1
  36. local end=$(date +%s%N)
  37. local duration=$(( (end - start) / 1000000 ))
  38. echo "$name: ${duration}ms"
  39. echo $duration
  40. }
  41. # Function to calculate throughput
  42. calc_throughput() {
  43. local operations=$1
  44. local time_ms=$2
  45. local ops_per_sec=$(echo "scale=2; $operations * 1000 / $time_ms" | bc)
  46. echo "$ops_per_sec"
  47. }
  48. # Cleanup
  49. cleanup() {
  50. echo -e "${YELLOW}Cleaning up...${NC}"
  51. rm -f $SQLITE_DB
  52. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  53. -H "Content-Type: application/json" \
  54. -d '{"sql":"DROP TABLE IF EXISTS benchmark_users"}' > /dev/null 2>&1 || true
  55. psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "DROP TABLE IF EXISTS benchmark_users" > /dev/null 2>&1 || true
  56. }
  57. trap cleanup EXIT
  58. echo -e "${GREEN}=== Benchmark 1: CREATE TABLE ===${NC}"
  59. echo ""
  60. # SQLite
  61. sqlite3 $SQLITE_DB "CREATE TABLE benchmark_users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, age INTEGER, created_at TEXT)"
  62. sqlite_create_time=$(time_command "SQLite CREATE" sqlite3 $SQLITE_DB "CREATE TABLE IF NOT EXISTS benchmark_test (id INTEGER PRIMARY KEY, value TEXT)")
  63. # PizzaSQL HTTP
  64. pizzasql_http_create_time=$(time_command "PizzaSQL HTTP CREATE" curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  65. -H "Content-Type: application/json" \
  66. -d '{"sql":"CREATE TABLE benchmark_users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, age INTEGER, created_at TEXT)"}')
  67. # PizzaSQL PostgreSQL
  68. pizzasql_pg_create_time=$(time_command "PizzaSQL PostgreSQL CREATE" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "CREATE TABLE IF NOT EXISTS benchmark_test (id INTEGER PRIMARY KEY, value TEXT)")
  69. echo ""
  70. echo -e "${GREEN}=== Benchmark 2: INSERT $NUM_ROWS Rows ===${NC}"
  71. echo ""
  72. # SQLite
  73. start=$(date +%s%N)
  74. for i in $(seq 1 $NUM_ROWS); do
  75. sqlite3 $SQLITE_DB "INSERT INTO benchmark_users (name, email, age, created_at) VALUES ('User$i', 'user$i@example.com', $((20 + $i % 50)), '2024-01-01')" 2>/dev/null
  76. done
  77. end=$(date +%s%N)
  78. sqlite_insert_time=$(( (end - start) / 1000000 ))
  79. sqlite_insert_ops=$(calc_throughput $NUM_ROWS $sqlite_insert_time)
  80. echo "SQLite INSERT: ${sqlite_insert_time}ms (${sqlite_insert_ops} ops/sec)"
  81. # PizzaSQL HTTP
  82. start=$(date +%s%N)
  83. for i in $(seq 1 $NUM_ROWS); do
  84. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  85. -H "Content-Type: application/json" \
  86. -d "{\"sql\":\"INSERT INTO benchmark_users (name, email, age, created_at) VALUES ('User$i', 'user$i@example.com', $((20 + $i % 50)), '2024-01-01')\"}" > /dev/null
  87. done
  88. end=$(date +%s%N)
  89. pizzasql_http_insert_time=$(( (end - start) / 1000000 ))
  90. pizzasql_http_insert_ops=$(calc_throughput $NUM_ROWS $pizzasql_http_insert_time)
  91. echo "PizzaSQL HTTP INSERT: ${pizzasql_http_insert_time}ms (${pizzasql_http_insert_ops} ops/sec)"
  92. # PizzaSQL PostgreSQL
  93. start=$(date +%s%N)
  94. for i in $(seq 1 $NUM_ROWS); do
  95. psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "INSERT INTO benchmark_users (name, email, age, created_at) VALUES ('User$i', 'user$i@example.com', $((20 + $i % 50)), '2024-01-01')" > /dev/null 2>&1
  96. done
  97. end=$(date +%s%N)
  98. pizzasql_pg_insert_time=$(( (end - start) / 1000000 ))
  99. pizzasql_pg_insert_ops=$(calc_throughput $NUM_ROWS $pizzasql_pg_insert_time)
  100. echo "PizzaSQL PostgreSQL INSERT: ${pizzasql_pg_insert_time}ms (${pizzasql_pg_insert_ops} ops/sec)"
  101. echo ""
  102. echo -e "${GREEN}=== Benchmark 3: SELECT (Full Table Scan) ===${NC}"
  103. echo ""
  104. # SQLite
  105. start=$(date +%s%N)
  106. for i in $(seq 1 100); do
  107. sqlite3 $SQLITE_DB "SELECT * FROM benchmark_users WHERE age > 30" > /dev/null
  108. done
  109. end=$(date +%s%N)
  110. sqlite_select_time=$(( (end - start) / 1000000 ))
  111. sqlite_select_ops=$(calc_throughput 100 $sqlite_select_time)
  112. echo "SQLite SELECT: ${sqlite_select_time}ms (${sqlite_select_ops} queries/sec)"
  113. # PizzaSQL HTTP
  114. start=$(date +%s%N)
  115. for i in $(seq 1 100); do
  116. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  117. -H "Content-Type: application/json" \
  118. -d '{"sql":"SELECT * FROM benchmark_users WHERE age > 30"}' > /dev/null
  119. done
  120. end=$(date +%s%N)
  121. pizzasql_http_select_time=$(( (end - start) / 1000000 ))
  122. pizzasql_http_select_ops=$(calc_throughput 100 $pizzasql_http_select_time)
  123. echo "PizzaSQL HTTP SELECT: ${pizzasql_http_select_time}ms (${pizzasql_http_select_ops} queries/sec)"
  124. # PizzaSQL PostgreSQL
  125. start=$(date +%s%N)
  126. for i in $(seq 1 100); do
  127. psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "SELECT * FROM benchmark_users WHERE age > 30" > /dev/null 2>&1
  128. done
  129. end=$(date +%s%N)
  130. pizzasql_pg_select_time=$(( (end - start) / 1000000 ))
  131. pizzasql_pg_select_ops=$(calc_throughput 100 $pizzasql_pg_select_time)
  132. echo "PizzaSQL PostgreSQL SELECT: ${pizzasql_pg_select_time}ms (${pizzasql_pg_select_ops} queries/sec)"
  133. echo ""
  134. echo -e "${GREEN}=== Benchmark 4: CREATE INDEX ===${NC}"
  135. echo ""
  136. # SQLite
  137. sqlite_index_time=$(time_command "SQLite CREATE INDEX" sqlite3 $SQLITE_DB "CREATE INDEX idx_age ON benchmark_users(age)")
  138. # PizzaSQL HTTP
  139. pizzasql_http_index_time=$(time_command "PizzaSQL HTTP CREATE INDEX" curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  140. -H "Content-Type: application/json" \
  141. -d '{"sql":"CREATE INDEX idx_age ON benchmark_users(age)"}')
  142. # PizzaSQL PostgreSQL
  143. pizzasql_pg_index_time=$(time_command "PizzaSQL PostgreSQL CREATE INDEX" psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "CREATE INDEX idx_age_pg ON benchmark_users(age)")
  144. echo ""
  145. echo -e "${GREEN}=== Benchmark 5: SELECT with INDEX ===${NC}"
  146. echo ""
  147. # SQLite
  148. start=$(date +%s%N)
  149. for i in $(seq 1 100); do
  150. sqlite3 $SQLITE_DB "SELECT * FROM benchmark_users WHERE age = 35" > /dev/null
  151. done
  152. end=$(date +%s%N)
  153. sqlite_indexed_time=$(( (end - start) / 1000000 ))
  154. sqlite_indexed_ops=$(calc_throughput 100 $sqlite_indexed_time)
  155. echo "SQLite SELECT (indexed): ${sqlite_indexed_time}ms (${sqlite_indexed_ops} queries/sec)"
  156. # PizzaSQL HTTP
  157. start=$(date +%s%N)
  158. for i in $(seq 1 100); do
  159. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  160. -H "Content-Type: application/json" \
  161. -d '{"sql":"SELECT * FROM benchmark_users WHERE age = 35"}' > /dev/null
  162. done
  163. end=$(date +%s%N)
  164. pizzasql_http_indexed_time=$(( (end - start) / 1000000 ))
  165. pizzasql_http_indexed_ops=$(calc_throughput 100 $pizzasql_http_indexed_time)
  166. echo "PizzaSQL HTTP SELECT (indexed): ${pizzasql_http_indexed_time}ms (${pizzasql_http_indexed_ops} queries/sec)"
  167. # PizzaSQL PostgreSQL
  168. start=$(date +%s%N)
  169. for i in $(seq 1 100); do
  170. psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "SELECT * FROM benchmark_users WHERE age = 35" > /dev/null 2>&1
  171. done
  172. end=$(date +%s%N)
  173. pizzasql_pg_indexed_time=$(( (end - start) / 1000000 ))
  174. pizzasql_pg_indexed_ops=$(calc_throughput 100 $pizzasql_pg_indexed_time)
  175. echo "PizzaSQL PostgreSQL SELECT (indexed): ${pizzasql_pg_indexed_time}ms (${pizzasql_pg_indexed_ops} queries/sec)"
  176. echo ""
  177. echo -e "${GREEN}=== Benchmark 6: UPDATE ===${NC}"
  178. echo ""
  179. # SQLite
  180. start=$(date +%s%N)
  181. for i in $(seq 1 100); do
  182. sqlite3 $SQLITE_DB "UPDATE benchmark_users SET age = age + 1 WHERE id = $i" > /dev/null
  183. done
  184. end=$(date +%s%N)
  185. sqlite_update_time=$(( (end - start) / 1000000 ))
  186. sqlite_update_ops=$(calc_throughput 100 $sqlite_update_time)
  187. echo "SQLite UPDATE: ${sqlite_update_time}ms (${sqlite_update_ops} ops/sec)"
  188. # PizzaSQL HTTP
  189. start=$(date +%s%N)
  190. for i in $(seq 1 100); do
  191. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  192. -H "Content-Type: application/json" \
  193. -d "{\"sql\":\"UPDATE benchmark_users SET age = age + 1 WHERE id = $i\"}" > /dev/null
  194. done
  195. end=$(date +%s%N)
  196. pizzasql_http_update_time=$(( (end - start) / 1000000 ))
  197. pizzasql_http_update_ops=$(calc_throughput 100 $pizzasql_http_update_time)
  198. echo "PizzaSQL HTTP UPDATE: ${pizzasql_http_update_time}ms (${pizzasql_http_update_ops} ops/sec)"
  199. # PizzaSQL PostgreSQL
  200. start=$(date +%s%N)
  201. for i in $(seq 1 100); do
  202. psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "UPDATE benchmark_users SET age = age + 1 WHERE id = $i" > /dev/null 2>&1
  203. done
  204. end=$(date +%s%N)
  205. pizzasql_pg_update_time=$(( (end - start) / 1000000 ))
  206. pizzasql_pg_update_ops=$(calc_throughput 100 $pizzasql_pg_update_time)
  207. echo "PizzaSQL PostgreSQL UPDATE: ${pizzasql_pg_update_time}ms (${pizzasql_pg_update_ops} ops/sec)"
  208. echo ""
  209. echo -e "${GREEN}=== Benchmark 7: Aggregate Query ===${NC}"
  210. echo ""
  211. # SQLite
  212. start=$(date +%s%N)
  213. for i in $(seq 1 100); do
  214. sqlite3 $SQLITE_DB "SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM benchmark_users GROUP BY age" > /dev/null
  215. done
  216. end=$(date +%s%N)
  217. sqlite_agg_time=$(( (end - start) / 1000000 ))
  218. sqlite_agg_ops=$(calc_throughput 100 $sqlite_agg_time)
  219. echo "SQLite AGGREGATE: ${sqlite_agg_time}ms (${sqlite_agg_ops} queries/sec)"
  220. # PizzaSQL HTTP
  221. start=$(date +%s%N)
  222. for i in $(seq 1 100); do
  223. curl -s -X POST "$PIZZASQL_HTTP_URL/query" \
  224. -H "Content-Type: application/json" \
  225. -d '{"sql":"SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM benchmark_users GROUP BY age"}' > /dev/null
  226. done
  227. end=$(date +%s%N)
  228. pizzasql_http_agg_time=$(( (end - start) / 1000000 ))
  229. pizzasql_http_agg_ops=$(calc_throughput 100 $pizzasql_http_agg_time)
  230. echo "PizzaSQL HTTP AGGREGATE: ${pizzasql_http_agg_time}ms (${pizzasql_http_agg_ops} queries/sec)"
  231. # PizzaSQL PostgreSQL
  232. start=$(date +%s%N)
  233. for i in $(seq 1 100); do
  234. psql -h $PIZZASQL_PG_HOST -p $PIZZASQL_PG_PORT -d pizzasql -c "SELECT age, COUNT(*) as count, AVG(id) as avg_id FROM benchmark_users GROUP BY age" > /dev/null 2>&1
  235. done
  236. end=$(date +%s%N)
  237. pizzasql_pg_agg_time=$(( (end - start) / 1000000 ))
  238. pizzasql_pg_agg_ops=$(calc_throughput 100 $pizzasql_pg_agg_time)
  239. echo "PizzaSQL PostgreSQL AGGREGATE: ${pizzasql_pg_agg_time}ms (${pizzasql_pg_agg_ops} queries/sec)"
  240. echo ""
  241. echo -e "${BLUE}========================================${NC}"
  242. echo -e "${BLUE}Summary${NC}"
  243. echo -e "${BLUE}========================================${NC}"
  244. echo ""
  245. printf "%-30s %-15s %-15s %-15s\n" "Operation" "SQLite" "PizzaSQL HTTP" "PizzaSQL PG"
  246. printf "%-30s %-15s %-15s %-15s\n" "------------------------------" "---------------" "---------------" "---------------"
  247. printf "%-30s %-15s %-15s %-15s\n" "INSERT ($NUM_ROWS rows)" "${sqlite_insert_ops} ops/s" "${pizzasql_http_insert_ops} ops/s" "${pizzasql_pg_insert_ops} ops/s"
  248. printf "%-30s %-15s %-15s %-15s\n" "SELECT (no index)" "${sqlite_select_ops} q/s" "${pizzasql_http_select_ops} q/s" "${pizzasql_pg_select_ops} q/s"
  249. printf "%-30s %-15s %-15s %-15s\n" "SELECT (indexed)" "${sqlite_indexed_ops} q/s" "${pizzasql_http_indexed_ops} q/s" "${pizzasql_pg_indexed_ops} q/s"
  250. printf "%-30s %-15s %-15s %-15s\n" "UPDATE" "${sqlite_update_ops} ops/s" "${pizzasql_http_update_ops} ops/s" "${pizzasql_pg_update_ops} ops/s"
  251. printf "%-30s %-15s %-15s %-15s\n" "AGGREGATE" "${sqlite_agg_ops} q/s" "${pizzasql_http_agg_ops} q/s" "${pizzasql_pg_agg_ops} q/s"
  252. echo ""
  253. echo -e "${GREEN}Benchmarks completed!${NC}"