Skip to content

CQL Performance ​

TL;DR ​

For the CQL queries analyzed here, the relative performance of query evaluation in patients/s stays the same for datasets with 1 million patients compared to datasets with 100 thousand patients if the system resources are sufficient and Blaze performs equally or better for datasets with more patient history. In all cases the performance increases with rising system resources.

Systems ​

The following systems, with increasing resources, were used for the performance evaluation:

SystemProviderCPUCoresRAMSSD
LEA25on-premEPYC 7543P432 GiB3.2 TB Intel P5600 over vSAN
LEA36on-premEPYC 7543P864 GiB3.2 TB Intel P5600 over vSAN
LEA47on-premEPYC 7543P16128 GiB3.2 TB Intel P5600 over vSAN
LEA58on-premEPYC 7543P32256 GiB3.2 TB Intel P5600 over vSAN
LEA79on-premEPYC 9555128512 GiB12.8 TB Huawei OceanDisk 300P
A5N46on-premRyzen 9900X2496 GiB4 TB Samsung 990 Pro

All systems were configured according to the Production Configuration guide.

On all systems, the heap memory and the block cache were each configured to use 1/4 of the total available RAM. Consequently, the Blaze process itself uses about half of the available system memory, leaving the remainder for the file system cache.

On A5N46, the measurements were done with direct reads in the resource database (RESOURCE_DB_DIRECT_READS=true and DB_RESOURCE_STORE_KV_THREADS=64), because its RAM is too small to keep both the index and the resource contents in the page cache. In addition, the heap was fixed with -Xms24g, so that the memory left for the page cache doesn't change while the JVM grows and shrinks its heap.

Datasets ​

The following datasets were used:

DatasetHistory# Pat. ¹# Res. ²# Obs. ³Size on SSD
100k10 years100 k104 M59 M110 GiB
100k-fhfull100 k317 M191 M323 GiB
1M10 years1 M1044 M593 M1045 GiB

¹ Number of Patients, ² Total Number of Resources, ³ Number of Observations

The creation of these datasets is described in the Synthea section. The disk size was measured after a full manual compaction of the database. The actual disk size can be up to 50% higher, depending on the state of the background compaction process.

Methods ​

Metric ​

The metric analyzed here are the number of patients a system can process per second. It was chosen because the CQL evaluation performance depends heavily on the number of patients available in Blaze. The datasets contain either 100 k or 1 million patients in order to represent two relevant sizes from where an interpolation or extrapolation towards the target size should be possible. The metric patients per second itself is independent from the actual number of patients and can therefore be used to compare the two population sizes analysed here.

With a given patients per second value, its always possible to calculate the to be expected CQL evaluation duration by dividing the target systems number of patients by that number. So for example, if the metric is 100 k patients/s Blaze will need 1 second if it contains 100 k patients and 5 seconds if it contains 500 k patients.

Measurement ​

Measurements are taken by using blazectl's evaluate-measure subcommand. That subcommand first creates both a Measure and a Library resource and evaluates the Measure afterwards. By creating resources on every run, there is a slight performance impact due to the way LSM trees used by RocksDB work. The measure evaluation returns a MeasureReport that contains the evaluation duration in an extension which ensures that external timing effects play no role.

Before each measurement Blaze is restarted. After that multiple runs are taken. The first run is used to obtain the number of hits and print the Bloom filter usage. It's duration isn't used. After this run the script waits for 10 seconds in order to give Blaze time to settle. During this time the Java just-in-time compiler and garbage collector and to some work. After that 9 runs are done were the duration for the first two runs are discarded. From the remaining 7 durations, the average and standard deviation are calculated. From the average and the total number of patients the final metric patients per second is calculated.

Systems ​

All measurements are taken on the same VM that has the size of LEA58. The OS is Ubuntu 22.04.4 LTS. Docker version is 26.1.4.

In this section, CQL queries for selecting patients which have observations with a certain code are analyzed. The codes were chosen to produce a wide range of hits (number of matching patients). For the 100k dataset the hits are 2 %, 60 % and 100 % of the total number of patients, for the 100k-fh dataset the hits are 2 %, 57 % and 100 % and for the 1M dataset the hits are 2.5 %, 60 % and 100 %.

Bar chart. Simple Code Search - Dataset 100k. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 2 % hits, 60 % hits, 100 % hits.Simple Code Search - Dataset 100k0 k500 k1000 k1500 k2000 kLEA25LEA36LEA47LEA58LEA25 · 2 % hits: 1540 kLEA36 · 2 % hits: 1972 kLEA47 · 2 % hits: 1975 kLEA58 · 2 % hits: 1942 kLEA25 · 60 % hits: 402.3 kLEA36 · 60 % hits: 819.7 kLEA47 · 60 % hits: 1363 kLEA58 · 60 % hits: 1351 kLEA25 · 100 % hits: 300.3 kLEA36 · 100 % hits: 562.5 kLEA47 · 100 % hits: 963.7 kLEA58 · 100 % hits: 1153 kPatients/sSystem2 % hits60 % hits100 % hits

The first chart shows the results for the 100k dataset. It shows that the performance raises with the system size and declines a lot with the number of patients found (hits). This decline can be explained because the Bloom filters are most effective for small number of hits.

Bar chart. Simple Code Search - Dataset 100k-fh. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 2 % hits, 57 % hits, 100 % hits.Simple Code Search - Dataset 100k-fh0 k500 k1000 k1500 k2000 kLEA25LEA36LEA47LEA58LEA25 · 2 % hits: 1513 kLEA36 · 2 % hits: 1913 kLEA47 · 2 % hits: 1981 kLEA58 · 2 % hits: 1979 kLEA25 · 57 % hits: 425.2 kLEA36 · 57 % hits: 756.3 kLEA47 · 57 % hits: 1370 kLEA58 · 57 % hits: 1367 kLEA25 · 100 % hits: 282.3 kLEA36 · 100 % hits: 487.2 kLEA47 · 100 % hits: 970.7 kLEA58 · 100 % hits: 1151 kPatients/sSystem2 % hits57 % hits100 % hits

The second bar chart shows the results for the 100k-fh dataset which differs by the 100 k dataset in that it contains a full history of patient data instead of a history capped at 10 years. Especially the number of observations is 191 M compared to only 59 M in the 100k dataset. Comparing the two bar charts, the performance is nearly identical. So for simple code search, the performance doesn't depend on the amount of patient history.

Bar chart. Simple Code Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58, LEA79, A5N46. Patients/s. Series: 2.5 % hits, 60 % hits, 100 % hits.Simple Code Search - Dataset 1M0 k1000 k2000 k3000 k4000 kLEA25LEA36LEA47LEA58LEA79A5N46LEA25 · 2.5 % hits: 1564 kLEA36 · 2.5 % hits: 2081 kLEA47 · 2.5 % hits: 1837 kLEA58 · 2.5 % hits: 2252 kLEA79 · 2.5 % hits: 4290 kA5N46 · 2.5 % hits: 4007 kLEA25 · 60 % hits: 135.9 kLEA36 · 60 % hits: 211.1 kLEA47 · 60 % hits: 1321 kLEA58 · 60 % hits: 2092 kLEA79 · 60 % hits: 3782 kA5N46 · 60 % hits: 3395 kLEA25 · 100 % hits: 88.1 kLEA36 · 100 % hits: 139.8 kLEA47 · 100 % hits: 1120 kLEA58 · 100 % hits: 1741 kLEA79 · 100 % hits: 3491 kA5N46 · 100 % hits: 2666 kPatients/sSystem2.5 % hits60 % hits100 % hits

The third bar chart shows the results for the 1M dataset. For the two bigger systems LEA47 and LEA58, the relative performance measured in patients per second is identical to the performance Blaze shows at the smaller datasets with only 100 k patients. However, the same can't be said for the two smaller systems LEA25 and LEA36, where the relative performance suffers due to memory limitations of those systems.

Data ​

DatasetSystemCode# HitsTime (s)StdDevPat./s
100kLEA2517861-62 k0.060.0031.540 M
100kLEA258310-560 k0.250.014402.3 k
100kLEA2572514-3100 k0.330.009300.3 k
100kLEA3617861-62 k0.050.0021.972 M
100kLEA368310-560 k0.120.005819.7 k
100kLEA3672514-3100 k0.180.004562.5 k
100kLEA4717861-62 k0.050.0011.975 M
100kLEA478310-560 k0.070.0021.363 M
100kLEA4772514-3100 k0.100.001963.7 k
100kLEA5817861-62 k0.050.0011.942 M
100kLEA588310-560 k0.070.0011.351 M
100kLEA5872514-3100 k0.090.0021.153 M
100k-fhLEA25788-02 k0.070.0031.513 M
100k-fhLEA2544261-657 k0.240.007425.2 k
100k-fhLEA2572514-3100 k0.350.007282.3 k
100k-fhLEA36788-02 k0.050.0021.913 M
100k-fhLEA3644261-657 k0.130.003756.3 k
100k-fhLEA3672514-3100 k0.210.006487.2 k
100k-fhLEA47788-02 k0.050.0021.981 M
100k-fhLEA4744261-657 k0.070.0011.370 M
100k-fhLEA4772514-3100 k0.100.001970.7 k
100k-fhLEA58788-02 k0.050.0021.979 M
100k-fhLEA5844261-657 k0.070.0021.367 M
100k-fhLEA5872514-3100 k0.090.0011.151 M
1MLEA2517861-625 k0.640.0051.564 M
1MLEA258310-5603 k7.360.041135.9 k
1MLEA2572514-3998 k11.350.09288.1 k
1MLEA3617861-625 k0.480.0032.081 M
1MLEA368310-5603 k4.740.038211.1 k
1MLEA3672514-3998 k7.150.032139.8 k
1MLEA4717861-625 k0.540.0081.837 M
1MLEA478310-5603 k0.760.0111.321 M
1MLEA4772514-3998 k0.890.0091.120 M
1MLEA5817861-625 k0.440.0092.252 M
1MLEA588310-5603 k0.480.0122.092 M
1MLEA5872514-3998 k0.570.0141.741 M
1MLEA7917861-625 k0.230.0034.290 M
1MLEA798310-5603 k0.260.0093.782 M
1MLEA7972514-3998 k0.290.0063.491 M
1MA5N4617861-625 k0.250.0084.007 M
1MA5N468310-5603 k0.290.0033.395 M
1MA5N4672514-3998 k0.380.0172.666 M

Example CQL Query ​

text
library "observation-17861-6"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

codesystem loinc: 'http://loinc.org'

context Patient

define InInitialPopulation:
  exists [Observation: Code '17861-6' from loinc]

The CQL queries can be executed with the following commands:

sh
cql/search.sh observation-17861-6
cql/search.sh observation-8310-5
cql/search.sh observation-72514-3
cql/search.sh observation-788-0
cql/search.sh observation-44261-6

In this section, CQL Queries for selecting patients which have observations with a certain code and value are analyzed. The values were chosen to produce a wide range of hits (number of matching patients). The hits are 10 %, 50 % and 100 %.

Bar chart. Code Value Search - Dataset 100k. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 10 % hits, 50 % hits, 100 % hits.Code Value Search - Dataset 100k0 k500 k1000 k1500 kLEA25LEA36LEA47LEA58LEA25 · 10 % hits: 356.9 kLEA36 · 10 % hits: 842.7 kLEA47 · 10 % hits: 1523 kLEA58 · 10 % hits: 1583 kLEA25 · 50 % hits: 137.7 kLEA36 · 50 % hits: 306 kLEA47 · 50 % hits: 676.3 kLEA58 · 50 % hits: 869.4 kLEA25 · 100 % hits: 93.7 kLEA36 · 100 % hits: 219.4 kLEA47 · 100 % hits: 440.1 kLEA58 · 100 % hits: 609.1 kPatients/sSystem10 % hits50 % hits100 % hits

The first chart shows the results for the 100k dataset. It shows the number of patients a system can process per second as described above. The performance raises with system size. As with Simple Code Search, queries with a small number of hits are much faster as queries with a large number of hits due to Bloom filter optimizations.

Bar chart. Code Value Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58, LEA79, A5N46. Patients/s. Series: 10 % hits, 50 % hits, 100 % hits.Code Value Search - Dataset 1M0 k1000 k2000 k3000 k4000 kLEA25LEA36LEA47LEA58LEA79A5N46LEA25 · 10 % hits: 852.6 kLEA36 · 10 % hits: 856.6 kLEA47 · 10 % hits: 2147 kLEA58 · 10 % hits: 2371 kLEA79 · 10 % hits: 4247 kA5N46 · 10 % hits: 3709 kLEA25 · 50 % hits: 129 kLEA36 · 50 % hits: 313.6 kLEA47 · 50 % hits: 1366 kLEA58 · 50 % hits: 2005 kLEA79 · 50 % hits: 4306 kA5N46 · 50 % hits: 3302 kLEA25 · 100 % hits: 12.8 kLEA36 · 100 % hits: 92.3 kLEA47 · 100 % hits: 881.3 kLEA58 · 100 % hits: 1545 kLEA79 · 100 % hits: 3559 kA5N46 · 100 % hits: 2565 kPatients/sSystem10 % hits50 % hits100 % hits

The second chart shows the results for the 1M dataset. Here the performance of the 10 % hits query is identical to that of the the 100k dataset. That can be explained because Bloom filter don't need much memory. However, the two smaller systems LEA25 and LEA36 show a degradation in the performance of the queries with larger number of hits. Here the memory limitations show while going into the actual database storage layer.

Data ​

DatasetSystemCodeValue# HitsTime (s)StdDevPat./s
100kLEA2529463-713.6 kg10 k0.280.010356.9 k
100kLEA2529463-775.3 kg50 k0.730.017137.7 k
100kLEA2529463-7185 kg100 k1.070.02993.7 k
100kLEA3629463-713.6 kg10 k0.120.008842.7 k
100kLEA3629463-775.3 kg50 k0.330.011306.0 k
100kLEA3629463-7185 kg100 k0.460.007219.4 k
100kLEA4729463-713.6 kg10 k0.070.0051.523 M
100kLEA4729463-775.3 kg50 k0.150.004676.3 k
100kLEA4729463-7185 kg100 k0.230.007440.1 k
100kLEA5829463-713.6 kg10 k0.060.0011.583 M
100kLEA5829463-775.3 kg50 k0.120.005869.4 k
100kLEA5829463-7185 kg100 k0.160.003609.1 k
1MLEA2529463-713.6 kg99 k1.170.075852.6 k
1MLEA2529463-775.3 kg500 k7.750.019129.0 k
1MLEA2529463-7185 kg998 k77.8728.63312.8 k
1MLEA3629463-713.6 kg99 k1.170.017856.6 k
1MLEA3629463-775.3 kg500 k3.190.052313.6 k
1MLEA3629463-7185 kg998 k10.830.08492.3 k
1MLEA4729463-713.6 kg99 k0.470.0072.147 M
1MLEA4729463-775.3 kg500 k0.730.0041.366 M
1MLEA4729463-7185 kg998 k1.130.025881.3 k
1MLEA5829463-713.6 kg99 k0.420.0082.371 M
1MLEA5829463-775.3 kg500 k0.500.0202.005 M
1MLEA5829463-7185 kg998 k0.650.0361.545 M
1MLEA7929463-713.6 kg99 k0.240.0014.247 M
1MLEA7929463-775.3 kg500 k0.230.0034.306 M
1MLEA7929463-7185 kg998 k0.280.0173.559 M
1MA5N4629463-713.6 kg99 k0.270.0103.709 M
1MA5N4629463-775.3 kg500 k0.300.0033.302 M
1MA5N4629463-7185 kg998 k0.390.0112.565 M

CQL Query ​

text
library "observation-body-weight-50"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

codesystem loinc: 'http://loinc.org'
code "body-weight": '29463-7' from loinc

context Patient

define InInitialPopulation:
  exists [Observation: "body-weight"] O where O.value < 75.3 'kg'

The CQL query is executed with the following command:

sh
cql/search.sh observation-body-weight-10
cql/search.sh observation-body-weight-50
cql/search.sh observation-body-weight-100

In this section, CQL queries for selecting patients which have conditions with one of 10 codes are analyzed. The codes were chosen to produce both a low number and a high number of hits. For the 100k dataset the hits are 0.4 % and 95 %, for the 100k-fh dataset the hits are 2 % and 98 % and for the 1M dataset the hits are 0.4 % and 95 %.

Bar chart. Ten Code Search - Dataset 100k. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 0.4 % hits, 95 % hits.Ten Code Search - Dataset 100k0 k500 k1000 k1500 kLEA25LEA36LEA47LEA58LEA25 · 0.4 % hits: 1524 kLEA36 · 0.4 % hits: 1677 kLEA47 · 0.4 % hits: 1772 kLEA58 · 0.4 % hits: 1653 kLEA25 · 95 % hits: 311.8 kLEA36 · 95 % hits: 568.2 kLEA47 · 95 % hits: 1005 kLEA58 · 95 % hits: 1105 kPatients/sSystem0.4 % hits95 % hits

The first chart shows the results for the 100k dataset. The performance raises with system size. As with Simple Code Search and Code Value Search, queries with a small number of hits are much faster as queries with a large number of hits due to Bloom filter optimizations.

Bar chart. Ten Code Search - Dataset 100k-fh. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 2 % hits, 98 % hits.Ten Code Search - Dataset 100k-fh0 k500 k1000 k1500 kLEA25LEA36LEA47LEA58LEA25 · 2 % hits: 660.7 kLEA36 · 2 % hits: 1184 kLEA47 · 2 % hits: 1578 kLEA58 · 2 % hits: 1536 kLEA25 · 98 % hits: 259.2 kLEA36 · 98 % hits: 553.7 kLEA47 · 98 % hits: 949.3 kLEA58 · 98 % hits: 1084 kPatients/sSystem2 % hits98 % hits

The second chart shows the results for the 100k-fh dataset. For the 100k-fh dataset the performance of the query with small number of hits is lower because the number of hits if actually larger (2 %) as that of the 100k dataset with 0.4 %.

Bar chart. Ten Code Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58, LEA79, A5N46. Patients/s. Series: 0.4 % hits, 95 % hits.Ten Code Search - Dataset 1M0 k1000 k2000 k3000 k4000 k5000 kLEA25LEA36LEA47LEA58LEA79A5N46LEA25 · 0.4 % hits: 1845 kLEA36 · 0.4 % hits: 1766 kLEA47 · 0.4 % hits: 2435 kLEA58 · 0.4 % hits: 2420 kLEA79 · 0.4 % hits: 4367 kA5N46 · 0.4 % hits: 4291 kLEA25 · 95 % hits: 110.1 kLEA36 · 95 % hits: 177.1 kLEA47 · 95 % hits: 1204 kLEA58 · 95 % hits: 1897 kLEA79 · 95 % hits: 3535 kA5N46 · 95 % hits: 2472 kPatients/sSystem0.4 % hits95 % hits

The third chart shows the results for the 1M dataset. As with the Code Value Search queries the performance for the query with low number of hits is the same across all system sizes, because Bloom filters don't need much memory. However, the same can't be said for the query with 95 % hits. Here the LEA25 and LEA36 systems are clearly too small.

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA253950.070.0041.524 M
100kLEA2595 k0.320.014311.8 k
100kLEA363950.060.0021.677 M
100kLEA3695 k0.180.005568.2 k
100kLEA473950.060.0011.772 M
100kLEA4795 k0.100.0011.005 M
100kLEA583950.060.0011.653 M
100kLEA5895 k0.090.0011.105 M
100k-fhLEA252 k0.150.008660.7 k
100k-fhLEA2598 k0.390.019259.2 k
100k-fhLEA362 k0.080.0011.184 M
100k-fhLEA3698 k0.180.004553.7 k
100k-fhLEA472 k0.060.0011.578 M
100k-fhLEA4798 k0.110.002949.3 k
100k-fhLEA582 k0.070.0011.536 M
100k-fhLEA5898 k0.090.0021.084 M
1MLEA254 k0.540.0041.845 M
1MLEA25954 k9.090.044110.1 k
1MLEA364 k0.570.0111.766 M
1MLEA36954 k5.650.033177.1 k
1MLEA474 k0.410.0072.435 M
1MLEA47954 k0.830.0091.204 M
1MLEA584 k0.410.0062.420 M
1MLEA58954 k0.530.0151.897 M
1MLEA794 k0.230.0034.367 M
1MLEA79954 k0.280.0113.535 M
1MA5N464 k0.230.0034.291 M
1MA5N46954 k0.400.0002.472 M

CQL Query Frequent ​

text
library "condition-ten-frequent"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

codesystem sct: 'http://snomed.info/sct'

context Patient

define InInitialPopulation:
  exists [Condition: Code '444814009' from sct] or
  exists [Condition: Code '840544004' from sct] or
  exists [Condition: Code '840539006' from sct] or
  exists [Condition: Code '386661006' from sct] or
  exists [Condition: Code '195662009' from sct] or
  exists [Condition: Code '49727002' from sct] or
  exists [Condition: Code '10509002' from sct] or
  exists [Condition: Code '72892002' from sct] or
  exists [Condition: Code '36955009' from sct] or
  exists [Condition: Code '162864005' from sct]
sh
cql/search.sh condition-ten-frequent

CQL Query Rare ​

text
library "condition-ten-rare"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

codesystem sct: 'http://snomed.info/sct'

context Patient

define InInitialPopulation:
  exists [Condition: Code '62718007' from sct] or
  exists [Condition: Code '234466008' from sct] or
  exists [Condition: Code '288959006' from sct] or
  exists [Condition: Code '47505003' from sct] or
  exists [Condition: Code '698754002' from sct] or
  exists [Condition: Code '157265008' from sct] or
  exists [Condition: Code '15802004' from sct] or
  exists [Condition: Code '14760008' from sct] or
  exists [Condition: Code '36923009' from sct] or
  exists [Condition: Code '45816000' from sct]
sh
cql/search.sh condition-ten-rare

Ten Code Search – ValueSet ​

In this section, CQL queries for selecting patients which have conditions with one of 10 codes are analyzed. The same codes as in section Ten Code Search are used. However, instead of multiple retrieve expressions, a single retrieve expression with a value set is used.

Bar chart. Ten Code Search – ValueSet - Dataset 1M. System: LEA47, LEA79, A5N46. Patients/s. Series: 0.4 % hits, 95 % hits.Ten Code Search – ValueSet - Dataset 1M0 k1000 k2000 k3000 k4000 kLEA47LEA79A5N46LEA47 · 0.4 % hits: 2227 kLEA79 · 0.4 % hits: 4052 kA5N46 · 0.4 % hits: 4565 kLEA47 · 95 % hits: 394.9 kLEA79 · 95 % hits: 2416 kA5N46 · 95 % hits: 714.6 kPatients/sSystem0.4 % hits95 % hits

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
1MLEA474 k0.450.0052.227 M
1MLEA47954 k2.530.007394.9 k
1MLEA794 k0.250.0014.052 M
1MLEA79954 k0.410.0042.416 M
1MA5N464 k0.220.0094.565 M
1MA5N46954 k1.400.002714.6 k

CQL Query Frequent ​

text
library "condition-ten-frequent-vs"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

valueset vs: 'http://fhir.org/VCL?v1=(http://snomed.info/sct)(72892002;10509002;36955009;195662009;162864005;49727002;444814009;386661006;840539006;840544004)'

context Patient

define InInitialPopulation:
  exists [Condition: vs]
sh
cql/search.sh condition-ten-frequent-vs

CQL Query Rare ​

text
library "condition-ten-rare-vs"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

valueset vs: 'http://fhir.org/VCL?v1=(http://snomed.info/sct)(62718007;234466008;288959006;47505003;698754002;157265008;15802004;14760008;36923009;45816000)'

context Patient

define InInitialPopulation:
  exists [Condition: vs]
sh
cql/search.sh condition-ten-rare-vs
Bar chart. All Code Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58, LEA79, A5N46. Patients/s for 100 % hits.All Code Search - Dataset 1M100 % hits0 k500 k1000 k1500 k2000 k2500 k3000 k3500 kLEA25LEA36LEA47LEA58LEA79A5N46LEA25 · 100 % hits: 103.5 kLEA36 · 100 % hits: 167.7 kLEA47 · 100 % hits: 981.3 kLEA58 · 100 % hits: 1674 kLEA79 · 100 % hits: 3411 kA5N46 · 100 % hits: 2188 kPatients/sSystem

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA2599 k0.350.013289.8 k
100kLEA3699 k0.190.003517.7 k
100kLEA4799 k0.110.001891.8 k
100kLEA5899 k0.100.0011.050 M
100k-fhLEA25100 k0.370.018273.0 k
100k-fhLEA36100 k0.200.006506.3 k
100k-fhLEA47100 k0.110.001870.3 k
100k-fhLEA58100 k0.100.0011.038 M
1MLEA25995 k9.660.041103.5 k
1MLEA36995 k5.960.015167.7 k
1MLEA47995 k0.890.0111.120 M
1MLEA58995 k0.600.0181.674 M
1MLEA79995 k0.290.0163.411 M
1MA5N46995 k0.460.0022.188 M

CQL Query ​

sh
cql/search.sh condition-all

All Code Search – ValueSet ​

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
1MLEA47995 k37.310.38726.8 k

CQL Query ​

sh
cql/search.sh condition-all
Bar chart. Inpatient Stress Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58, LEA79, A5N46. Patients/s for 1.6 % hits.Inpatient Stress Search - Dataset 1M1.6 % hits0 k500 k1000 k1500 k2000 k2500 k3000 k3500 kLEA25LEA36LEA47LEA58LEA79A5N46LEA25 · 1.6 % hits: 275 kLEA36 · 1.6 % hits: 256.7 kLEA47 · 1.6 % hits: 805 kLEA58 · 1.6 % hits: 1478 kLEA79 · 1.6 % hits: 3508 kA5N46 · 1.6 % hits: 1613 kPatients/sSystem

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA252 k0.590.017169.1 k
100kLEA362 k0.310.009326.7 k
100kLEA472 k0.170.004580.5 k
100kLEA582 k0.150.005683.1 k
100k-fhLEA252 k1.890.01652.8 k
100k-fhLEA362 k1.150.01486.9 k
100k-fhLEA472 k0.780.004127.9 k
100k-fhLEA582 k0.540.006184.4 k
1MLEA2516 k3.640.064275.0 k
1MLEA3616 k3.900.041256.7 k
1MLEA4716 k1.240.008805.0 k
1MLEA5816 k0.680.0181.478 M
1MLEA7916 k0.290.0013.508 M
1MA5N4616 k0.620.0061.613 M

CQL Query ​

sh
cql/search.sh inpatient-stress

Medication ​

Bar chart. Medication Search - Dataset 100k. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 1 % hits, 7 % hits.Medication Search - Dataset 100k0 k500 k1000 k1500 k2000 kLEA25LEA36LEA47LEA58LEA25 · 1 % hits: 806.4 kLEA36 · 1 % hits: 1684 kLEA47 · 1 % hits: 1930 kLEA58 · 1 % hits: 1889 kLEA25 · 7 % hits: 854.3 kLEA36 · 7 % hits: 1637 kLEA47 · 7 % hits: 1900 kLEA58 · 7 % hits: 1800 kPatients/sSystem1 % hits7 % hits
Bar chart. Medication Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58. Patients/s. Series: 1 % hits, 7 % hits.Medication Search - Dataset 1M0 k500 k1000 k1500 k2000 kLEA25LEA36LEA47LEA58LEA25 · 1 % hits: 720.1 kLEA36 · 1 % hits: 1440 kLEA47 · 1 % hits: 2145 kLEA58 · 1 % hits: 2085 kLEA25 · 7 % hits: 765.3 kLEA36 · 7 % hits: 1478 kLEA47 · 7 % hits: 2214 kLEA58 · 7 % hits: 2140 kPatients/sSystem1 % hits7 % hits
DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA259660.120.004806.4 k
100kLEA257 k0.120.006854.3 k
100kLEA369660.060.0031.684 M
100kLEA367 k0.060.0021.637 M
100kLEA479660.050.0001.930 M
100kLEA477 k0.050.0011.900 M
100kLEA589660.050.0011.889 M
100kLEA587 k0.060.0011.800 M
1MLEA2510 k1.390.005720.1 k
1MLEA2566 k1.310.011765.3 k
1MLEA3610 k0.690.0031.440 M
1MLEA3666 k0.680.0071.478 M
1MLEA4710 k0.470.0022.145 M
1MLEA4766 k0.450.0042.214 M
1MLEA5810 k0.480.0032.085 M
1MLEA5866 k0.470.0032.140 M

CQL Queries ​

sh
cql/search.sh medication-1
cql/search.sh medication-7

Medication Ten ​

Bar chart. Medication Ten Search - Dataset 100k. System: LEA25, LEA36, LEA47, LEA58. Patients/s for 15 % hits.Medication Ten Search - Dataset 100k15 % hits0 k200 k400 k600 k800 k1000 k1200 k1400 k1600 kLEA25LEA36LEA47LEA58LEA25 · 15 % hits: 533.7 kLEA36 · 15 % hits: 1022 kLEA47 · 15 % hits: 1486 kLEA58 · 15 % hits: 1491 kPatients/sSystem
Bar chart. Medication Ten Search - Dataset 1M. System: LEA25, LEA36, LEA47, LEA58. Patients/s for 15 % hits.Medication Ten Search - Dataset 1M15 % hits0 k200 k400 k600 k800 k1000 k1200 k1400 k1600 kLEA25LEA36LEA47LEA58LEA25 · 15 % hits: 353.4 kLEA36 · 15 % hits: 719.4 kLEA47 · 15 % hits: 1393 kLEA58 · 15 % hits: 1574 kPatients/sSystem
DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA2515 k0.190.009533.7 k
100kLEA3615 k0.100.0021.022 M
100kLEA4715 k0.070.0021.486 M
100kLEA5815 k0.070.0011.491 M
1MLEA25149 k2.830.026353.4 k
1MLEA36149 k1.390.004719.4 k
1MLEA47149 k0.720.0061.393 M
1MLEA58149 k0.640.0031.574 M

Cardiometabolic Risk ​

In this section, a CQL query combining multiple criteria with time dependencies is analyzed. Unlike the queries above, which test a single criterion, it selects patients with a diabetes or prediabetes diagnosis at an age between 18 and 75 that has all of the following around it:

  • a BMI of at least 30 kg/m² within one year of the diagnosis,
  • an HbA1c above 6.0 % within two years after the diagnosis,
  • a hypertension diagnosis before or within one year after the diagnosis,
  • a systolic blood pressure above 130 mmHg within one year of the diagnosis, and
  • an inpatient or emergency encounter within five years after the diagnosis.

Because every criterion relates to the same diagnosis, all conditions, observations and encounters involved have to be loaded and compared to its onset for every patient that has such a diagnosis.

The measurement was done with the CQL expression cache disabled. With the cache enabled, the duration drops to 0.21 seconds on A5N46, as soon as the Bloom filter of the exists expression is built, because only the patients in the Bloom filter have to be evaluated.

Bar chart. Cardiometabolic Risk - Dataset 1M. System: LEA47, LEA79, A5N46. Patients/s for 0.1 % hits.Cardiometabolic Risk - Dataset 1M0.1 % hits0 k200 k400 k600 k800 k1000 k1200 kLEA47LEA79A5N46LEA47 · 0.1 % hits: 5.1 kLEA79 · 0.1 % hits: 1194 kA5N46 · 0.1 % hits: 21 kPatients/sSystem

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
1MLEA471 k196.6054.5105.1 k
1MLEA791 k0.840.0191.194 M
1MA5N461 k47.630.79821.0 k

CQL Query ​

text
library "cardiometabolic-risk"
using FHIR version '4.0.0'
include FHIRHelpers version '4.0.0'

codesystem sct: 'http://snomed.info/sct'
codesystem loinc: 'http://loinc.org'
codesystem act: 'http://terminology.hl7.org/CodeSystem/v3-ActCode'

valueset "Diabetes or Prediabetes": 'http://fhir.org/VCL?v1=(http://snomed.info/sct)(44054006;15777000)'

code "Hypertension": '59621000' from sct
code "HbA1c": '4548-4' from loinc
code "BMI": '39156-5' from loinc
code "Blood Pressure": '85354-9' from loinc
code "Systolic Blood Pressure": '8480-6' from loinc
code "Inpatient": 'IMP' from act
code "Emergency": 'EMER' from act

context Patient

define "Metabolic Diagnosis":
  [Condition: "Diabetes or Prediabetes"] D
    where AgeInYearsAt(D.onset as dateTime) between 18 and 75

define "Obesity":
  [Observation: "BMI"] O
    where O.value >= 30 'kg/m2'

define "Elevated HbA1c":
  [Observation: "HbA1c"] O
    where O.value > 6.0 '%'

define "Elevated Systolic Blood Pressure":
  [Observation: "Blood Pressure"] O
    where exists (O.component C
      where C.code ~ ToConcept("Systolic Blood Pressure")
        and C.value > 130 'mm[Hg]')

define "Hospitalization":
  [Encounter] E
    where E.class ~ "Inpatient" or E.class ~ "Emergency"

define "Index Diagnosis":
  "Metabolic Diagnosis" D
    with "Obesity" O
      such that (O.effective as dateTime) within 1 year of (D.onset as dateTime)
    with "Elevated HbA1c" A
      such that (A.effective as dateTime) 2 years or less after (D.onset as dateTime)
    with [Condition: "Hypertension"] H
      such that (H.onset as dateTime) on or before (D.onset as dateTime) + 1 year
    with "Elevated Systolic Blood Pressure" P
      such that (P.effective as dateTime) within 1 year of (D.onset as dateTime)
    with "Hospitalization" E
      such that E.period.start 5 years or less after (D.onset as dateTime)

define InInitialPopulation:
  exists "Index Diagnosis"
sh
cql/search.sh cardiometabolic-risk

Condition Code Stratification ​

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA585.2 M12.790.3257.8 k
1MLEA5852.3 M399.6411.9662.5 k
1MLEA7952.3 M80.924.55012.4 k
1MA5N4652.3 M267.654.8293.7 k

CQL Queries ​

sh
cql/search.sh stratifier-condition-code

Laboratory Observation Code Stratification ​

Data ​

DatasetSystem# HitsTime (s)StdDevPat./s
100kLEA5837.8 M280.403.0260
1MLEA79380.5 M1138.857.6990
1MA5N46380.5 M2768.199.3100

CQL Queries ​

sh
cql/search.sh stratifier-observation-laboratory-code