Function
They mean different things. The asterisk matches zero to infinity characters. The question mark matches exactly one character.
From the references above:
The * character serves as a "wild card" for filename expansion in globbing.
The ? character serves as a single-character "wild card" for filename expansion in globbing…
Performance
tl;dr: there is no detectable difference in performance.
I tested performance by using a directory filled with 36 sub-directories, each named with a single character. There were about 70 000 files in the subdirectories combined. I tested the following.
$ time ls ?/* -d >/dev/null
$ time ls */* -d >/dev/null
I alternated each command ten times each. Here are the results for the real
time, in seconds.
? *
0.318 0.326
0.355 0.212
0.291 0.351
0.291 0.265
0.287 0.283
0.362 0.23
0.248 0.33
0.286 0.283
0.293 0.351
0.233 0.352
After statistical analysis (paired t-test, two-tailed), I could detect no difference between the two values in performance (p value = 0.95).

EDIT: More samples
I repeated the above analysis with 200 samples each, again alternating tests.
$ for i in {1..200}; do time (ls */* -d >/dev/null) 2>> /tmp/time_asterisk; time (ls ?/* -d >/dev/null) 2>> /tmp/time_question_mark; done
Here are the raw data for ? and *. Again, I could detect no significant difference (p value = 0.55), and the distribution of each test looks more similar.
